无锁队列的实现
根据网上各种博客,然后自己写的一个无锁队列。
以后尝试性用这个代替线程池中的任务队列,应该这样会快很多。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <thread> 3 #include <atomic> 4 5 template<class T> 6 class LinkNode { 7 public: 8 T data; 9 LinkNode<T> *next; 10 }; 11 12 template<class T> 13 class LockFreeQueue { 14 public: 15 LockFreeQueue<T>() : head_(nullptr), tail_(nullptr), len(0) { 16 LinkNode<T> *now = new LinkNode<T>; 17 now->next = nullptr; 18 head_ = tail_ = now; 19 } 20 void push(const T &data); 21 T pop_front(); 22 bool empty(); 23 private: 24 LinkNode<T> *head_; 25 LinkNode<T> *tail_; 26 std::atomic_int len; 27 }; 28 29 template <class T> 30 void LockFreeQueue<T>::push(const T &data) { 31 LinkNode<T> * now = new LinkNode<T>; 32 now->data=data; 33 now->next= nullptr; 34 LinkNode<T> * p1,*nxt; 35 while(1){ 36 p1 = tail_; 37 nxt = tail_->next; 38 if (p1!=tail_) continue; 39 if(nxt!= nullptr) { 40 __sync_bool_compare_and_swap(&tail_,p1,nxt); 41 continue; 42 } 43 if (__sync_bool_compare_and_swap(&tail_->next,nxt,now)==1) { 44 break; 45 } 46 } 47 __sync_bool_compare_and_swap(&tail_,p1,now); 48 len++; 49 } 50 51 template <class T> 52 T LockFreeQueue<T>::pop_front() { 53 LinkNode<T> *p1; 54 do{ 55 p1=head_->next; 56 if (p1== nullptr) { 57 return -999999; 58 } 59 }while(__sync_bool_compare_and_swap(&head_->next,p1,p1->next)!=true); 60 len--; 61 return p1->data; 62 } 63 64 template <class T> 65 bool LockFreeQueue<T>::empty() { 66 if (len==0) return true; 67 else return false; 68 } 69 70 LockFreeQueue<int> queue; 71 72 void func1(void) { 73 for (int i = 0; i < 10; i++) { 74 queue.push(i); 75 } 76 } 77 78 void func2(void) { 79 for (int i = 30; i < 40; i++) { 80 queue.push(i); 81 } 82 } 83 84 void func3(void) { 85 for (int i = 0; i < 10; i++) { 86 std::cout << queue.pop_front() << " "; 87 } 88 std::cout << std::endl; 89 } 90 91 int main(int argc, char **argv) { 92 std::thread t1(func1); 93 std::thread t2(func2); 94 std::thread t3(func3); 95 std::thread t4(func3); 96 t1.join(); 97 t2.join(); 98 t3.join(); 99 t4.join(); 100 return 0; 101 }