上源码

 #ifndef __GLOBAL_LOCK_FREE_QUEUE_H__
#define __GLOBAL_LOCK_FREE_QUEUE_H__ #include <atomic>
#include <list> #ifdef _WINDOWS
#include <windows.h>
//PVOID __cdecl InterlockedCompareExchangePointer(
// _Inout_ PVOID volatile *Destination,
// _In_ PVOID Exchange,
// _In_ PVOID Comparand
// );
//
//Parameters
// Destination [in, out]
//A pointer to a pointer to the destination value.
// Exchange [in]
//The exchange value.
// Comparand [in]
//The value to compare to Destination.
// Return value
// The function returns the initial value of the Destination parameter.
// Remarks
// The function compares the Destination value with the Comparand value. If the Destination value is equal to the Comparand value, the Exchange value is stored in the address specified by Destination. Otherwise, no operation is performed.
// On a 64-bit system, the parameters are 64 bits and must be aligned on 64-bit boundaries; otherwise, the function will behave unpredictably. On a 32-bit system, the parameters are 32 bits and must be aligned on 32-bit boundaries.
// The interlocked functions provide a simple mechanism for synchronizing access to a variable that is shared by multiple threads. This function is atomic with respect to calls to other interlocked functions.
#define __sync_bool_compare_and_swap(a,b,c) (InterlockedCompareExchangePointer((void*volatile*)a,c,b), (*a)==(c))
#endif namespace DataCache
{ template <typename T>
class LinkList
{
public:
T data;
LinkList<T> *next;
};// class LinkeList<T> template <typename T>
class LockFreeQueue
{
public:
LockFreeQueue(); void push_back(T t); T pop_front(void); bool isEmpty(void); int GetLength(); private:
LinkList<T> *head_;
LinkList<T> *tail_;
std::_Atomic_integral_t elementNumbers_;
}; // class LockFreeQueue template <typename T>
LockFreeQueue<T>::LockFreeQueue()
:head_(NULL),
tail_(new LinkList<T>),
elementNumbers_()
{
head_ = tail_;
tail_->next = NULL;
} template <typename T>
void LockFreeQueue<T>::push_back(T t)
{
auto newVal = new LinkList<T>;
newVal->data = t;
newVal->next = NULL; LinkList<T> *p;
do
{
p = tail_;
} while (!__sync_bool_compare_and_swap(&tail_->next, NULL, newVal)); //move tail_
__sync_bool_compare_and_swap(&tail_, tail_, newVal);
elementNumbers_++;
} template <typename T>
T LockFreeQueue<T>::pop_front()
{
LinkList<T> *p; do
{
//record the first node.
p = head_->next;
if (!p)
{
return ;
}
} while (!__sync_bool_compare_and_swap(&head_->next, p, p->next)); if (elementNumbers_ > ) elementNumbers_--;
if (elementNumbers_ == )
{
// if the queue is empty then the tail to header.
do
{ } while (!__sync_bool_compare_and_swap(&tail_, p, head_));
} return p->data;
} template <typename T>
bool LockFreeQueue<T>::isEmpty()
{
if (elementNumbers_ == )
{
return true;
}
else
{
return false;
}
} template <typename T>
int LockFreeQueue<T>::GetLength()
{
return elementNumbers_;
} }// namespace DataCache #endif

源码解析:

重点在函数InterlockedCompareExchangePointer(a,c,b),其作用为如果a==b,则修改a的值为c,这是微软提供的一个原子操作的API,这里面通过定义这个宏,来进行queue入队列和出队列时的指针修改,达到无锁操作的目的,可以大幅提高队列的操作性能,避免过程中进行加锁操作。在GCC中已经原生支持了__sync_bool_compare_and_swap,所以这个宏的作用是针对MSVC版本提供的类似函数。

测试代码:

 #include"lockFreeQueue.h"

 DataCache::LockFreeQueue<int> queue;

 void func1(void)
{
for(int i = ; i < ; i++)
{
queue.push_back(i);
}
} void func2(void)
{
for(int i = ; i < ; i++)
{
queue.push_back(i);
}
} void func5(void)
{
for(int i = ; i < ; i++)
{
queue.push_back(i);
}
} void func4(void)
{
for(int i = ; i < ; i++)
{
queue.push_back(i);
}
} void func3(void)
{
while (!queue.isEmpty())
{
std::cout<<queue.pop_front()<<" ";
} std::cout<<std::endl;
} int main(int argc,char **argv)
{
std::thread t1(func1);
std::thread t2(func2);
std::thread t5(func5);
std::thread t6(func4); t1.join();
t2.join();
t5.join();
t6.join(); int length=queue.GetLength();
assert(length==500000);
return ;
}

C++ 无锁队列实现的更多相关文章

  1. 无锁队列以及ABA问题

    队列是我们非常常用的数据结构,用来提供数据的写入和读取功能,而且通常在不同线程之间作为数据通信的桥梁.不过在将无锁队列的算法之前,需要先了解一下CAS(compare and swap)的原理.由于多 ...

  2. HashMap的原理与实 无锁队列的实现Java HashMap的死循环 red black tree

    http://www.cnblogs.com/fornever/archive/2011/12/02/2270692.html https://zh.wikipedia.org/wiki/%E7%BA ...

  3. zeromq源码分析笔记之无锁队列ypipe_t(3)

    在上一篇中说到了mailbox_t的底层实际上使用了管道ypipe_t来存储命令.而ypipe_t实质上是一个无锁队列,其底层使用了yqueue_t队列,ypipe_t是对yueue_t的再包装,所以 ...

  4. boost 无锁队列

    一哥们翻译的boost的无锁队列的官方文档 原文地址:http://blog.csdn.net/great3779/article/details/8765103 Boost_1_53_0终于迎来了久 ...

  5. 一个可无限伸缩且无ABA问题的无锁队列

    关于无锁队列,详细的介绍请参考陈硕先生的<无锁队列的实现>一文.然进一步,如何实现一个不限node数目即能够无限伸缩的无锁队列,即是本文的要旨. 无锁队列有两种实现形式,分别是数组与链表. ...

  6. 无锁队列--基于linuxkfifo实现

    一直想写一个无锁队列,为了提高项目的背景效率. 有机会看到linux核心kfifo.h 原则. 所以这个实现自己仿照,眼下linux我们应该能够提供外部接口. #ifndef _NO_LOCK_QUE ...

  7. CAS简介和无锁队列的实现

    Q:CAS的实现 A:gcc提供了两个函数 bool __sync_bool_compare_and_swap (type *ptr, type oldval, type newval, ...)// ...

  8. Go语言无锁队列组件的实现 (chan/interface/select)

    1. 背景 go代码中要实现异步很简单,go funcName(). 但是进程需要控制协程数量在合理范围内,对应大批量任务可以使用"协程池 + 无锁队列"实现. 2. golang ...

  9. 基于无锁队列和c++11的高性能线程池

    基于无锁队列和c++11的高性能线程池线程使用c++11库和线程池之间的消息通讯使用一个简单的无锁消息队列适用于linux平台,gcc 4.6以上   标签: <无>   代码片段(6)[ ...

  10. folly无锁队列正确性说明

    folly无锁队列是facebook开源的一个无所队列,使用的是单向链表,通过compare_exchange语句实现的多生产多消费的队列,我曾经花了比较多的时间学习memory_order的说明,对 ...

随机推荐

  1. Redis学习第八课:Redis高级实用特性(一)

    Redis高级实用特性 注:我学习的环境是vmware7.1 + ubantu10.10+ redis 3.0.2 1.安全性 设置客户端连接后进行任何其他指定前需要的密码.因为redis速度相当快, ...

  2. C高级第一次PTA作业

    作业要求一 附加题目 写程序证明P++等价于(p)++还是等价于*(p++)? 1.设计思路: (1).题目算法描述 第一步:定义变量p并赋初值 第二步:分三次计算每次分别输出 p++,(p)++,* ...

  3. linux-*.filetype.bz2 unzip

    how to unzip *.bz2 file? wget http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2 unzip ...

  4. Unity 3D中 Ulua-UGUI简单的Demo——热更新的具体流程、使用说明

    Ulua热更新具体流程.使用说明 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 -- 未完 1 -- ...

  5. Ubuntu 18.04 搜狗输入法无法切换到英文输入

    不知道改了个什么东西,Ubuntu 中Ctrl+Space不能切换输入法了,因此不能输入英文,shell就更是没法工作,最后找到方法了: 在终端键入fcitx-config-gtk3,这时候如果直接在 ...

  6. with() {} 的用法

    var use = "other"; var katana = { isSharp: true, use: function(){ this.isSharp = !!this.is ...

  7. TP框架连接mongodb报错及解决办法

    mongodb版本3.4.7 1.认证错误:Failed to connect to: localhost:27017: Authentication failed on database 'test ...

  8. HDU1070:Milk

    Milk Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  9. hdu2085-2086

    hdu2085 模拟 #include<stdio.h> ][]; void fun(){ a[][]=; a[][]=; ;i<=;i++){ a[i][]=*a[i-][]+*a ...

  10. 【MVC】知识笔记

    MVC代表:模型-视图-控制器. Models:标识该应用程序的数据并使用验证逻辑来强制实施业务规则的数据类 Views  :应用程序动态生成HTML所使用的模版文件 Controllers:处理浏览 ...