Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.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++ 如果跨2个线程使用,那么是否值得将大小声明为std::atomic?_C++_Thread Safety_Stdatomic_Size T - Fatal编程技术网

C++ 如果跨2个线程使用,那么是否值得将大小声明为std::atomic?

C++ 如果跨2个线程使用,那么是否值得将大小声明为std::atomic?,c++,thread-safety,stdatomic,size-t,C++,Thread Safety,Stdatomic,Size T,我有一个size\u t变量,它由一个std::thread更新,并由另一个std::thread读取 我知道我可以对读写进行互斥保护。 但是,如果我将size\u t设置为std::atomic,这是相同的还是有益的?是的,这是值得的。事实上,如果多个线程使用同一个变量,并且至少有一个线程正在写入该变量,则必须使用std::atomic或同步对非原子的访问。 不遵循此规则是数据竞争未定义行为 根据您对std::size_t的使用情况,编译器可以假定非原子变量和其他非同步变量不会从其他线程更改,

我有一个
size\u t
变量,它由一个
std::thread
更新,并由另一个
std::thread
读取

我知道我可以对读写进行互斥保护。
但是,如果我将
size\u t
设置为
std::atomic
,这是相同的还是有益的?

是的,这是值得的。事实上,如果多个线程使用同一个变量,并且至少有一个线程正在写入该变量,则必须使用
std::atomic
或同步对非原子的访问。 不遵循此规则是数据竞争未定义行为

根据您对std::size_t的使用情况,编译器可以假定非原子变量和其他非同步变量不会从其他线程更改,并相应地优化代码。这会导致不好的事情™ 发生

我通常的例子是使用非原子布尔值的循环:

//使keepRunning成为std::atomic以避免无休止的循环
布尔·基普朗宁{true};
无符号数=0;
无效停止()
{
保持修剪=错误;
}
void循环()
{
同时(继续修剪){
数字+=1;
}
}
在编译启用优化的代码时,GCC和Clang都只会检查
keepRunning
一次,然后开始一个无休止的循环。 有关生成的汇编程序输出,请参见

i、 他们将其优化为
if(keepRunning)无限循环,将负载吊出回路。因为它是非原子的,所以他们可以假设没有其他线程可以编写它。有关同一问题的更详细信息,请参阅

请注意,此示例仅在循环体足够简单时显示错误。但是,未定义的行为仍然存在,应该通过使用std::atomic或synchronization来避免


在这种情况下,您可以将
std::atomic
std::memory\u order\u relaxed
一起使用,因为您不需要任何同步或排序wrt。写入线程或读取线程中的其他操作。这将赋予您原子性(无撕裂)和值可以异步更改的假设,而无需编译器使用任何asm屏障指令来创建更多排序wrt。其他行动

因此,在不进行任何同步的情况下使用原子是可能的,也是安全的,甚至不需要像seq_cst或acquire/release加载和存储那样在编写器和读取器之间创建同步。您可以使用此同步来安全地共享非原子变量或数组,例如与
原子缓冲区
,读卡器在指针非空时读取该缓冲区


但是,如果只共享原子变量本身,则可以让读取器读取当前值,而不必关心同步。如果不需要重新读取短循环的每个迭代,每次函数调用只需一次,那么您可能希望将其读入本地临时文件。

是的,这是值得的。事实上,如果多个线程使用同一个变量,并且至少有一个线程正在写入该变量,则必须使用
std::atomic
或同步对非原子的访问。 不遵循此规则是数据竞争未定义行为

根据您对std::size_t
的使用情况,编译器可以假定非原子变量和其他非同步变量不会从其他线程更改,并相应地优化代码。这会导致不好的事情™ 发生

我通常的例子是使用非原子布尔值的循环:

//使keepRunning成为std::atomic以避免无休止的循环
布尔·基普朗宁{true};
无符号数=0;
无效停止()
{
保持修剪=错误;
}
void循环()
{
同时(继续修剪){
数字+=1;
}
}
在编译启用优化的代码时,GCC和Clang都只会检查
keepRunning
一次,然后开始一个无休止的循环。 有关生成的汇编程序输出,请参见

i、 他们将其优化为
if(keepRunning)无限循环,将负载吊出回路。因为它是非原子的,所以他们可以假设没有其他线程可以编写它。有关同一问题的更详细信息,请参阅

请注意,此示例仅在循环体足够简单时显示错误。但是,未定义的行为仍然存在,应该通过使用std::atomic或synchronization来避免


在这种情况下,您可以将
std::atomic
std::memory\u order\u relaxed
一起使用,因为您不需要任何同步或排序wrt。写入线程或读取线程中的其他操作。这将赋予您原子性(无撕裂)和值可以异步更改的假设,而无需编译器使用任何asm屏障指令来创建更多排序wrt。其他行动

因此,在不进行任何同步的情况下使用原子是可能的,也是安全的,甚至不需要像seq_cst或acquire/release加载和存储那样在编写器和读取器之间创建同步。您可以使用此同步来安全地共享非原子变量或数组,例如与
原子缓冲区
,读卡器在指针非空时读取该缓冲区


但是,如果只共享原子变量本身,则可以让读取器读取当前值,而不必关心同步。如果不需要重新读取短循环的每个迭代,每次函数调用只需一次,则可能需要将其读入本地临时文件。

IMHO原子很好,但必须小心使用正确的方法。例如,必须以正确的方式执行递增/递减。看看这一点:IMHO原子学很不错,但你必须小心正确使用它们。例如,必须以正确的方式执行递增/递减。看看这个:同步不是强制性的,你可以使用
内存\u顺序\u松弛
,因此读者只需读取