Mat*_*247 5 c++ lambda multithreading capture thread-local
我目前正在构建一个系统,其中有多个线程正在运行,一个线程可以将工作排队到另一个线程并等待完成。我使用互斥体和条件变量进行同步。为了避免为每个操作创建新的互斥体和 cv,我想对其进行优化,并尝试为每个正在等待的线程使用 thread_local 互斥体/cv 对。然而,这出乎意料地不起作用,我很有趣为什么。
基本上我的代码将工作排队到另一个线程并等待它,如下所示:
/* thread_local */ std::mutex mtx;
/* thread_local */ std::condition_variable cv;
bool done = false;
io_service.post([&]() {
// Execute the handler in context of the io thread
functionWhichNeedsToBeCalledInOtherThread();
// Signal completion to unblock the waiter
{
std::lock_guard<std::mutex> lock(mtx);
done = true;
}
cv.notify_one();
});
// Wait until queued work has been executed in io thread
{
std::unique_lock<std::mutex> lk(mtx);
while (!done) cv.wait(lk);
}
Run Code Online (Sandbox Code Playgroud)
如果同步对象不是,则此方法可以正常工作thread_local。当我添加thread_local等待线程时,它会永远等待,这表明条件变量永远不会发出信号。我现在有一种感觉,尽管通过引用捕获对象,但另一个线程的 thread_local 对象在 lambda 内部使用。mtx我什至可以通过检查lambda 内部和外部的地址来确认捕获没有执行正确的操作-> 它们不匹配。
问题是:
thread_local变量?thread_local我可以通过创建对lambda 外部变量的显式引用并在其中使用这些引用来解决该错误。然而,我认为这种行为是出乎意料的,并且很想听到解释这是否是正确的行为。
您观察到的是正确的行为,因为您实际上没有捕获任何内容。静态和线程存储持续时间对象可以直接访问,因此为了提高效率[&]-capture 对这些对象没有影响。但是,您可以显式捕获适当的线程本地实例:
io_service.post([&mtx = mtx, &cv = cv]() {
Run Code Online (Sandbox Code Playgroud)