C++ 通过引用捕获lambda中的本地对象是否会导致数据竞争?
我有一段代码在运行时使用线程消毒剂时导致错误:C++ 通过引用捕获lambda中的本地对象是否会导致数据竞争?,c++,multithreading,thread-sanitizer,data-race,C++,Multithreading,Thread Sanitizer,Data Race,我有一段代码在运行时使用线程消毒剂时导致错误: bool Renderer::render(std::optional<int32_t> cancellationToken) { const RenderWatcher renderWatcher{cancellationToken}; ... return Render(... [&renderWatcher]() { return !renderWatcher.i
bool Renderer::render(std::optional<int32_t> cancellationToken) {
const RenderWatcher renderWatcher{cancellationToken};
...
return Render(...
[&renderWatcher]() { return !renderWatcher.isRenderInProgress(); });
}
还有一些人:
bool RenderWatcher::isRenderInProgress() const {
if (!cancellationToken) {
return true;
}
...
}
lambda[&renderWatcher](){return!renderWatcher.isRenderInProgress();}
是存储在私有字段中的boost::async
实例,询问“是否可以取消此渲染过程?”
设置cancellationToken时,TSAN竞争在RenderWatcher
构造函数中,而RenderWatcher.isRenderInProgress
在读取cancellationToken
时没有互斥锁
如果RenderWatcher是一个局部变量,但它是通过lambda中的引用捕获的,那么我可以进行数据竞争吗
按价值捕获解决了竞争:
[renderWatcher]() { return !renderWatcher.isRenderInProgress(); }
或使用互斥锁进行保护:
bool RenderWatcher::isRenderInProgress() const {
// Lock mutex here
if (!cancellationToken) {
return true;
}
...
}
这是一场真正的数据竞赛吗?通过引用或通过值进行捕获有什么不同
谢谢。整个设计在我看来有点可疑,但是没有看到一个完整的示例来显示系统的所有组件,在哪个线程中完成了什么,等等,这有点难说。您返回一个捕获本地引用的lambda。那不是无效的吗?是的,这就是问题所在。ASAN在返回后显示更清晰的
堆栈使用
冲突。
bool RenderWatcher::isRenderInProgress() const {
// Lock mutex here
if (!cancellationToken) {
return true;
}
...
}