c – 使用boost :: atomic的无锁队列 – 我这样做了吗?
精简版:
我试图从here替换无锁,单生成器,单消费者队列实现中使用的C 11中的std :: atomic.如何用 长版: 我正试图通过工作线程从我们的应用程序中获得更好的性能.每个线程都有自己的任务队列.我们必须在出列/排队每个任务之前使用锁同步. 然后我找到了Herb Sutter关于无锁队列的文章.这似乎是一个理想的替代品.但代码使用了C 11中的std :: atomic,目前我无法将其引入到项目中. 更多的谷歌搜索导致了一些例子,例如this one for Linux (echelon’s)和this one for Windows (TINESWARE’s).两者都使用平台的特定构造,如WinAPI的InterlockedExchangePointer和GCC的__sync_lock_test_and_set. 我只需要支持Windows& Linux也许我可以逃脱一些#ifdefs.但我认为使用boost :: atomic提供的东西可能更好. Boost Atomic尚未成为官方Boost库的一部分.所以我从http://www.chaoticmind.net/~hcb/projects/boost.atomic/下载了源代码并在我的项目中使用了包含文件. 这是我到目前为止所得到的: #pragma once #include <boost/atomic.hpp> template <typename T> class LockFreeQueue { private: struct Node { Node(T val) : value(val),next(NULL) { } T value; Node* next; }; Node* first; // for producer only boost::atomic<Node*> divider; // shared boost::atomic<Node*> last; // shared public: LockFreeQueue() { first = new Node(T()); divider = first; last= first; } ~LockFreeQueue() { while(first != NULL) // release the list { Node* tmp = first; first = tmp->next; delete tmp; } } void Produce(const T& t) { last.load()->next = new Node(t); // add the new item last = last.load()->next; while(first != divider) // trim unused nodes { Node* tmp = first; first = first->next; delete tmp; } } bool Consume(T& result) { if(divider != last) // if queue is nonempty { result = divider.load()->next->value; // C: copy it back divider = divider.load()->next; return true; // and report success } return false; // else report empty } }; 需要注意的一些修改: boost::atomic<Node*> divider; // shared boost::atomic<Node*> last; // shared 和 last.load()->next = new Node(t); // add the new item last = last.load()->next; 和 result = divider.load()->next->value; // C: copy it back divider = divider.load()->next; 我是否正确地在boost :: atomic中应用了load()(以及隐式store())?我们可以说这相当于Sutter原来的C 11无锁队列吗? PS.我在SO上研究了许多线程,但似乎没有一个提供boost :: atomic& amp;无锁队列. 解决方法
你试过
Intel Thread Building Blocks’原子< T>?跨平台和免费.
也… 单个生产者/单个消费者使您的问题更容易,因为您的线性化点可以是单个运算符.如果您准备接受有界队列,它会变得更容易. 有界队列提供缓存性能的优势,因为您可以保留缓存对齐的内存块以最大化您的命中,例如: #include <vector> #include "tbb/atomic.h" #include "tbb/cache_aligned_allocator.h" template< typename T > class SingleProdcuerSingleConsumerBoundedQueue { typedef vector<T,cache_aligned_allocator<T> > queue_type; public: BoundedQueue(int capacity): queue(queue_type()) { head = 0; tail = 0; queue.reserve(capacity); } size_t capacity() { return queue.capacity(); } bool try_pop(T& result) { if(tail - head == 0) return false; else { result = queue[head % queue.capacity()]; head.fetch_and_increment(); //linearization point return(true); } } bool try_push(const T& source) { if(tail - head == queue.capacity()) return(false); else { queue[tail % queue.capacity()] = source; tail.fetch_and_increment(); //linearization point return(true); } } ~BoundedQueue() {} private: queue_type queue; atomic<int> head; atomic<int> tail; }; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |