多线程安全无锁消息队列

技术介绍:

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

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字节的无关数据。



你可能感兴趣的:(多线程编程)