多线程安全无锁消息队列

来源:互联网 发布:it程序员面试自我介绍 编辑:程序博客网 时间:2024/06/10 03:27

技术介绍:

cas 原子操作:是有cpu提供的原子操作。

<pre name="code" class="cpp">MyDeque{  Node *head;  Node *tail;  void enQueue(T value);  T deQueue();}


入队操作

void enQueue(T value){     node * q=getNewNode();     q->next=null;     q->value=T;     // 通过原子操作把q加入到队列      while(1)     {             node *tem=tail;             while(tem->next!=null) //防止其他线程已经把元素加入队列,但是没有更新tail                  tem=tem->next;             if( CAS(&tail->next,null,q))                 break;     }     //通过援助操作,更新tail      CAS(&tail,tail,tail->next);     }

出对操作


T deQueue(){  while(1)  {          node *q=head;          if(q->next==null)//没有元素,带头结点的队列             return null;                      if(CAS( &head ,q,head->next)) 更新head             break;  }  T temValue=q->value;  recycle(q); //回收空间   return temValue;
}
以上是队列出对入队操作,

Pseudocode from article of the above name in PODC96 (with two typos corrected), by Maged M. Michael and Michael L. Scott


关于该算法的一些优化

1.该算法的入队时候需要重新分配空间,分配空间这个开销是很大的,实际上可以不用每次入队都分配工具,可以是实现个多线程安全的freeList,用来存放可用的空间结点,每次入队了,从freeList得到一个空间,加入队列。出队时,可是把该空间加入到freeList,这样可以节省空间分配和回收的开销,同时也可以避免ABA问题。这个方法可以参考lmax disruptor.

2.关于伪共享的问题,需要cache line填充。在head,tail之间可以填充64字节的无关数据。



原创粉丝点击