C++ 无锁队列实现
上源码
#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++ 无锁队列实现的更多相关文章
- 无锁队列以及ABA问题
队列是我们非常常用的数据结构,用来提供数据的写入和读取功能,而且通常在不同线程之间作为数据通信的桥梁.不过在将无锁队列的算法之前,需要先了解一下CAS(compare and swap)的原理.由于多 ...
- HashMap的原理与实 无锁队列的实现Java HashMap的死循环 red black tree
http://www.cnblogs.com/fornever/archive/2011/12/02/2270692.html https://zh.wikipedia.org/wiki/%E7%BA ...
- zeromq源码分析笔记之无锁队列ypipe_t(3)
在上一篇中说到了mailbox_t的底层实际上使用了管道ypipe_t来存储命令.而ypipe_t实质上是一个无锁队列,其底层使用了yqueue_t队列,ypipe_t是对yueue_t的再包装,所以 ...
- boost 无锁队列
一哥们翻译的boost的无锁队列的官方文档 原文地址:http://blog.csdn.net/great3779/article/details/8765103 Boost_1_53_0终于迎来了久 ...
- 一个可无限伸缩且无ABA问题的无锁队列
关于无锁队列,详细的介绍请参考陈硕先生的<无锁队列的实现>一文.然进一步,如何实现一个不限node数目即能够无限伸缩的无锁队列,即是本文的要旨. 无锁队列有两种实现形式,分别是数组与链表. ...
- 无锁队列--基于linuxkfifo实现
一直想写一个无锁队列,为了提高项目的背景效率. 有机会看到linux核心kfifo.h 原则. 所以这个实现自己仿照,眼下linux我们应该能够提供外部接口. #ifndef _NO_LOCK_QUE ...
- CAS简介和无锁队列的实现
Q:CAS的实现 A:gcc提供了两个函数 bool __sync_bool_compare_and_swap (type *ptr, type oldval, type newval, ...)// ...
- Go语言无锁队列组件的实现 (chan/interface/select)
1. 背景 go代码中要实现异步很简单,go funcName(). 但是进程需要控制协程数量在合理范围内,对应大批量任务可以使用"协程池 + 无锁队列"实现. 2. golang ...
- 基于无锁队列和c++11的高性能线程池
基于无锁队列和c++11的高性能线程池线程使用c++11库和线程池之间的消息通讯使用一个简单的无锁消息队列适用于linux平台,gcc 4.6以上 标签: <无> 代码片段(6)[ ...
- folly无锁队列正确性说明
folly无锁队列是facebook开源的一个无所队列,使用的是单向链表,通过compare_exchange语句实现的多生产多消费的队列,我曾经花了比较多的时间学习memory_order的说明,对 ...
随机推荐
- WTForms组件
WTForms组件 WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证. 注意: from wtforms import Form 和 from flask_wtf ...
- A+B for Input-Output Practice (VII)
A+B for Input-Output Practice (VII) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 ...
- Thumbnailator java图片压缩,加水印,批量生成缩略图
地址:http://code.google.com/p/thumbnailator/ 1.指定大小进行缩放 //size(宽度, 高度) /* * 若图片横比200小,高比300小,不变 * 若图片横 ...
- OpenCV Error: Insufficient memory问题解析
前言 项目程序运行两个月之久之后突然挂了,出现OpenCV Error: Insufficient memory的错误,在此分析一下该问题. 问题的表现形式: 程序内存使用情况: 问题: OpenCV ...
- ReSharper2017.3的列对齐、排版格式、列对齐错误的修复
ReSharper代码排版格式 列对齐 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...
- ubuntu 部署wordPress
准备 LAMP 环境 1.安装 Apache2 sudo apt-get install apache2 -y 安装好后,您可以通过访问服务器IP地址 x.x.x.x 查看到 “it works” 界 ...
- 洛谷 1020:导弹拦截(DP,LIS)
题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...
- Microsoft - Find the K closest points to the origin in a 2D plane
Find the K closest points to the origin in a 2D plane, given an array containing N points. 用 max hea ...
- asp.net excel 操作
/// <summary> /// 数据操作 /// </summary> /// <param name="fileName"></pa ...
- opencv mat flags含义
f:\opencv\opencv\sources\modules\core\src\matrix.cpp: flags = (_type & CV_MAT_TYPE_MASK) | MAGI ...