多线程安全无锁消息队列

技术介绍:

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



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值