可能重复:
C++中是否存在生产就绪无锁队列或散列实现
我正在寻找一个经过充分测试,公开可用的无锁队列的C/C++实现.
我至少需要多个生产者/单一消费者功能.如果存在,多用户甚至更好.
我正在瞄准VC的_Interlocked...内在函数,尽管任何直接进入端口的东西都可以.
任何人都可以给出任何指示吗?
有谁知道在Haskell中是否可以进行无锁编程?我对于是否有适当的低级基元是否可用以及(如果有的话)关于在纯函数上下文中使用这些基元来构建工作大规模系统的任何信息感兴趣.(我以前从未在纯函数上下文中完成无锁编程.)例如,据我所知,Control.Concurrent.Chan通道是建立在MVars之上的,据我所知,它使用了锁 - - 原则上可以构建Chan原语的版本,这些版本在内部是无锁的吗?希望获得多少性能提升?
我也shoudl说,我熟悉TVars的存在,但并不了解其内部实现---我一直在考虑要明白,他们大多是无锁的,但我不知道,如果他们完全锁定免费.所以关于TVars内部实现的任何信息也会有所帮助!
(这个帖子提供了一些讨论,但我想知道是否有更新更新/更全面.)
我<thread> <atomic> <mutex>在代码中使用了很多,其中包括几个无锁算法.我的目标是(最终)一个linux环境.我一直在使用Visual Studio 2011 Beta开发,虽然在其他C++ 11功能中缺乏可怕性,但它似乎是实现并发功能的唯一工具链.
请参阅此处的c ++ 11支持:
现在如果其他人只是缺少一个包含c ++ 11并发功能的库,我可以很容易地使用just :: thread,但是clang和gcc都对c ++ 11内存模型回答"否",至少visual c ++似乎支持.我不确定这会产生什么影响 - 可能会优化掉明显无副作用的代码,以及其他错误的东西.
如果现在我完全避免优化构建并且只编译调试版本而不启用优化 - 使用Clang或GCC工具链是否合理?
我在jsr166中读取了FutureTask类,发现结果对象是非易失性的,代码中的注释是"非易失性的,受状态读/写保护"第75行,状态是volatile int.我从Java Language Spec读过Java Memory Model ,但没有找到准确的答案.有人知道原因吗?
.Net框架Interlocked.Add()只有int和的方法long.但我需要Interlock.Add()的double类型.我怎样才能做到这一点?
我该如何使用boost::lockfree:queue物体?
我正在尝试编写一个通过默认构造函数构造此类对象的应用程序,但它在boost源中给出了一个断言失败:
BOOST_ASSERT(has_capacity);
Run Code Online (Sandbox Code Playgroud)
如何使用此类的默认构造函数?我是否需要通过模板参数指定队列的大小?
我正在使用boost spsc_queue将我的东西从一个线程移动到另一个线程.它是我软件中的关键位置之一,所以我希望尽快完成.我写了这个测试程序:
#include <boost/lockfree/spsc_queue.hpp>
#include <stdint.h>
#include <condition_variable>
#include <thread>
const int N_TESTS = 1000;
int results[N_TESTS];
boost::lockfree::spsc_queue<int64_t, boost::lockfree::capacity<1024>> testQueue;
using std::chrono::nanoseconds;
using std::chrono::duration_cast;
int totalQueueNano(0);
int totalQueueCount(0);
void Consumer() {
int i = 0;
int64_t scheduledAt;
while (i < N_TESTS - 1) {
while (testQueue.pop(scheduledAt)) {
int64_t dequeuedAt = (duration_cast<nanoseconds>(
std::chrono::high_resolution_clock::now().time_since_epoch())).count();
auto diff = dequeuedAt - scheduledAt;
totalQueueNano += diff;
++totalQueueCount;
results[i] = diff;
++i;
}
}
for (int i = 0; i < N_TESTS; i++) {
printf("%d …Run Code Online (Sandbox Code Playgroud) 在试图理解如何处理无锁代码的过程中,我试图编写单个消费者/单生产者锁定免费队列.和往常一样,我检查了论文,文章和代码,特别是考虑到这是一个有点微妙的主题.
所以,我偶然发现了Folly库中这个数据结构的实现,可以在这里找到:https: //github.com/facebook/folly/blob/master/folly/ProducerConsumerQueue.h
正如我看到的每个无锁队列,这个似乎使用循环缓冲区,所以我们有两个std::atomic<unsigned int>变量:readIndex_和writeIndex_.该readIndex_指示下一个索引,我们将读取,并writeIndex_在其中我们将写入下一个.看起来很简单.
因此,初看起来看起来很干净,很简单,但我发现有一件事很麻烦.事实上,一些功能,如isEmpty(),isFull()或guessSize()使用std::memory_order_consume检索索引的价值.
公平地说,我真的不知道他们的目的是什么.不要误解我的意思,我知道std::memory_order_consume在经典的依赖项中使用了一个原子指针,但是在这里,我们似乎没有任何依赖!我们只得到索引,无符号整数,我们不创建依赖项.在这种情况下,对我来说,a std::memory_order_relaxed是等价的.
但是,我不相信自己比设计此代码的人更了解内存排序,因此我在这里问这个问题.有什么我错过或误解了吗?
我提前感谢你的答案!
我正在开发一个多核,多线程软件库,我想在其中提供可能跨越多个缓存行的更新顺序保留无锁共享内存对象.
具体来说,假设我有一些高速缓存行大小的对象的向量X:X [0],... X [K]每个占用恰好一个高速缓存行.我按索引顺序写入它们:首先是X [0],然后是X [1],等等.如果线程2读取X [K],它还会看到X [0]的状态是"至少是当前的"正如它看到的X [K]?
从同一个线程,显然我会看到尊重更新顺序的内存语义.但是现在如果某个第二个线程读取X [K]则会出现问题:是否会观察到对X [0] ...... X [K-1]的相应更新?
通过锁定,我们可以获得此保证.但是由于memcpy用于将某些东西复制到向量中,我们失去了这个属性:memcpy有一个POSIX语义,它不保证索引顺序更新或内存顺序更新或任何其他排序.您可以确保在memcpy完成后,已执行整个更新.
我的问题:是否已经有一个保持订单的memcpy具有相似的速度但具有所需的保证?如果没有,可以在没有锁定的情况下实现这样的原语吗?
假设我的目标平台是x86和ARM.
(编者注:最初称英特尔,所以OP可能不关心AMD.)
在C#中,volatile关键字分别确保读取和写入具有获取和释放语义.但是,是否有关于引入读取或写入的内容?
例如:
volatile Thing something;
volatile int aNumber;
void Method()
{
// Are these lines...
var local = something;
if (local != null)
local.DoThings();
// ...guaranteed not to be transformed into these by compiler, jitter or processor?
if (something != null)
something.DoThings(); // <-- Second read!
// Are these lines...
if (aNumber == 0)
aNumber = 1;
// ...guaranteed not to be transformed into these by compiler, jitter or processor?
var temp = aNumber;
if (temp == 0) …Run Code Online (Sandbox Code Playgroud)