Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过引用捕获lambda中的本地对象是否会导致数据竞争?_C++_Multithreading_Thread Sanitizer_Data Race - Fatal编程技术网

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;
    }
    ...
}