我目前一直在使用基于Herb Sutter's presentation的并发对象。我目前正在使用带有11月CTP的Visual Studio 2012(无法以其他方式检查下面的内容,Clang不喜欢decltypes中的类成员,g ++在Windows上不喜欢任何东西)。
这样做,我遇到了一个奇怪的bug,其中thread-id为-1。 请考虑以下代码:
__workerThread([=]() -> void {
std::cerr << std::endl;
while (!__done)
{
this->__innerqueue.pop()();
}
})
这只是带有lambda函数的std::thread
的初始化 - 没什么了不起的,我想。
但是没有第一行强制调用std :: cerr(没有优化),这个线程的id似乎是-1(由于调试器),否则就像它应该的那样。
执行
时出现此线程ID的问题std::unique_lock<std::mutex> lock(this->__accessMutex);
在message-queue内部,因为它在较低的API(mutex.c)中的某处崩溃。
有谁知道可能导致这种奇怪行为的原因?将呼叫添加到std::cerr
目前只是一个讨厌的解决方法,我想摆脱它......
如果您想要使用它,可以在Github找到完整的来源。
答案 0 :(得分:3)
它看起来像初始化程序问题。线程在完全创建并发队列(竞争)之前运行。 std::cerr
可能会使线程延迟足够长的时间以使其正常工作。
尝试交换两行:
std::thread __workerThread;
mutable concurrent::queue<std::function<void()>, std::queue> __innerqueue;
交换应该在线程之前创建__innerqueue
,它应该像宣传的那样工作。