上源码

 #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. [leetcode] 94. Binary Tree Inorder Traversal 二叉树的中序遍历

    题目大意 https://leetcode.com/problems/binary-tree-inorder-traversal/description/ 94. Binary Tree Inorde ...

  2. 第十章 企业项目开发--分布式缓存Redis(2)

    注意:本章代码是在上一章的基础上进行添加修改,上一章链接<第九章 企业项目开发--分布式缓存Redis(1)> 上一章说了ShardedJedisPool的创建过程,以及redis五种数据 ...

  3. URL的应用

    1.对于Android来说,开发应用都会去访问服务器地址,那么就要连网,需要通过URL. 先new一个URL来获取路径,然后利用HttpURLConnection来连接并打开url,并通过get 请求 ...

  4. [LeetCode&Python] Problem 693. Binary Number with Alternating Bits

    Given a positive integer, check whether it has alternating bits: namely, if two adjacent bits will a ...

  5. 《DSP using MATLAB》Problem 3.9

    利用的频移性质为: 本习题代码: %% ------------------------------------------------------------------------ %% Outp ...

  6. hdu1114 dp(完全背包)

    题意:已知空钱罐质量和满钱罐质量(也就是知道钱罐里的钱的质量),知道若干种钱币每种的质量以及其价值,钱币都是无限个,问最少钱罐中有多少钱. 这个题在集训的时候学长给我们做过,所以你会做是应该的,由于已 ...

  7. Django FBV和CBV -

    一.FBV和CBV 在Python菜鸟之路:Django 路由.模板.Model(ORM)一节中,已经介绍了几种路由的写法及对应关系,那种写法可以称之为FBV: function base view ...

  8. sql server 创建内联表值函数

    表值函数就是返回table 的函数使用它可以方便的进行查询的处理 创建的代码如下: create FUNCTION returunclassfirstlist(  -- Add the paramet ...

  9. html 滚动固定显示js脚本

    <script type="text/javascript">function htmlScroll(){ var top = document.body.scroll ...

  10. Java中 @Override 的作用

    @Override是伪代码,表示重写(当然不写也可以),不过写上有如下好处: 可以当注释用,方便阅读: 编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错.例如,你如 ...