Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.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++ 为什么线程消毒剂会抱怨这个std::ranges::views::filter代码?_C++_Race Condition_C++20_Range V3 - Fatal编程技术网

C++ 为什么线程消毒剂会抱怨这个std::ranges::views::filter代码?

C++ 为什么线程消毒剂会抱怨这个std::ranges::views::filter代码?,c++,race-condition,c++20,range-v3,C++,Race Condition,C++20,Range V3,运行此代码时,线程消除器将处理有关数据竞争的问题。 为什么? #包括 #包括 #包括 #包括 int main(){ std::向量v{11,22,33,44,55,66}; 自动查看=v |标准::范围::视图::过滤器([](常量自动x){ 返回x>47; }); std::jthread jt1([&]{ 整数和=0; 对于(const auto&val:view){sum+=val;} }); std::jthread jt2([&]{ 整数和=0; 对于(const auto&

运行此代码时,线程消除器将处理有关数据竞争的问题。 为什么?

#包括
#包括
#包括
#包括
int main(){
std::向量v{11,22,33,44,55,66};
自动查看=v |标准::范围::视图::过滤器([](常量自动x){
返回x>47;
});
std::jthread jt1([&]{
整数和=0;
对于(const auto&val:view){sum+=val;}
});    
std::jthread jt2([&]{
整数和=0;
对于(const auto&val:view){sum+=val;}
});
}

注:我知道这个问题的答案,我最近在一次演讲中了解到了这个问题,但我发现它非常令人惊讶,并且没有任何与此相关的问题,所以我想与大家分享。如果没有人对回答感兴趣,我会自己回答。

[&]
在运行lambda的线程中,应该会立即发出警报。通过非
const
引用将随机对象传递给线程通常是不安全的。特别是,在标准库对象上调用非
const
成员函数不是线程安全的

begin
不是
std::ranges::filter\u视图的
const
成员函数

constexpr迭代器begin()
应为:
pred\u.has\u value()

返回:
{*this,ranges::find_if(base_u,ref(*pred_u))}

备注:为了提供范围概念要求的摊销固定时间复杂性, 此函数将结果缓存在
filter\u视图中
,以便在后续调用中使用

在libstdc++实现中,正是这个缓存操作触发了线程清理程序

试图使
视图
恒定会导致编译错误

反向视图
也是如此

其他范围适配器的
const
重载用于
begin

实际上,在构造线程之前,可以通过调用
view.begin()
来解决这个问题。我不知道这是否会使未定义的行为正式消失(我认为可能应该),但它确实让消毒剂保持沉默

#include <iostream>
#include <ranges>
#include <thread>
#include <vector>

int main(){
    std::vector v{11,22,33,44,55,66};
    auto view = v | std::ranges::views::filter([](const auto x){
        return x>47;
    });
    std::jthread jt1([&]{
    int sum =0;
    for (const auto& val: view) {sum+=val;}
    });    
    std::jthread jt2([&]{
    int sum =0;
    for (const auto& val: view) {sum+=val;}
    });
}