上源码

 #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. 一个TED演讲背后的文化论

    0. 前言 写这个前言让我很难受,当然不是心情难受哈,此时的状态是很High的哦,大中午觉都省了, 说难受是我觉得我这语言文字太渣了,相比今天的主题确实很没“文化”.但我也很庆幸,能 看到这么个人认为 ...

  2. OO面向对象多线程编程作业总结

    第五次作业:多线程电梯调度 设计策略 ​ 在本次电梯作业当中,我构造了一个电梯请求队列线程,一个调度器线程,三个电梯线程,一个文件输出线程,还有主线程. ​ 调度器扫描用户的请求队列,将每个队列分配给 ...

  3. uDig配图与GeoServer添加Style

    软件介绍: uDig是一个开源的桌面GIS软件,可以进行shp与栅格数据地图文件的编辑和查看,对OpenGIS标准,关于互联网GIS.网络地图服务器和网络功能服务器有特别的加强.通常和GeoServe ...

  4. iconfont 入门级使用方法

    iconfont : what? 阿里妈妈MUX倾力打造的矢量图标管理.交流平台.设计师将图标上传到Iconfont平台,用户可以自定义下载多种格式的icon,平台也可将图标转换为字体,便于前端工程师 ...

  5. magento开发中文手册

    Magento开发 第一章 手册简介Introduction 对一个开发人员来说,电子商务开发也许是现今最具创造性的工作.在这个瞬息万变的网络世界,为了保持始终领先竞争对手一步,无论是对你自己还是你的 ...

  6. Error: timed out while waiting for target halted

    /************************************************************************************ * Error: timed ...

  7. U盘安装电脑系统教程

    [怎么使用u盘安装系统.U盘装系统.如何用U盘安装系统.U盘制作系统.U盘引导.U盘启动.U盘量产.安装系统.如何设置U盘启动] 在电脑系统的日常使用中,经常会遇到系统崩溃或重新安装系统的情况,没有光 ...

  8. MySQL主从复制报错及解决方法

    mysql> show slave status \G *************************** 1. row *************************** Slave_ ...

  9. (2)流程控制(for循环、if...else判断、while循环)

    for循环 for item in names:  #结构语法 print(item) for循环嵌套for循环 for循环配合range()可以直接指定要打印的数量 例:打印一个金字塔 for i ...

  10. 一篇文章入门Jmeter性能测试【经典长文】

    孟船长  目录 1.性能测试定义2.为什么要做性能测试3.性能测试指标.性能测试分类4.Jmeter性能测试实战[入门级]5.参考文章链接 1.性能测试定义 百度&知乎 性能测试是通过自动化的 ...