Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.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++代码。它有一个关键部分: lock.Acquire(); current_id = shared_id; // small amounts of other code shared_id = (shared_id + 1) % max_id; lock.Release(); // do something with current_id_C++_Concurrency - Fatal编程技术网

带锁的语句重新排序 这里是一些从多个线程并行访问的C++代码。它有一个关键部分: lock.Acquire(); current_id = shared_id; // small amounts of other code shared_id = (shared_id + 1) % max_id; lock.Release(); // do something with current_id

带锁的语句重新排序 这里是一些从多个线程并行访问的C++代码。它有一个关键部分: lock.Acquire(); current_id = shared_id; // small amounts of other code shared_id = (shared_id + 1) % max_id; lock.Release(); // do something with current_id,c++,concurrency,C++,Concurrency,lock变量的类是POSIX互斥实现的包装器。由于模块操作,不可能使用原子操作 具有O3标志的gcc编译器是否可能优化代码,以便在锁定之前移动当前\u id的分配?通常,编译器不应进行此类有害的优化。如果您仍然不确定,可以使用关键字来阻止对该id变量进行优化。可以使用O3进行编译 除非函数被标记为纯使用函数属性,否则编译器永远不会在函数调用中进行优化 互斥函数不是纯粹的,因此与O3一起使用绝对安全。volatile不会阻止所有相关的优化。它阻止值缓存在寄存器中,但几乎没有其他功能。读/写操作仍然

lock变量的类是POSIX互斥实现的包装器。由于模块操作,不可能使用原子操作


具有O3标志的gcc编译器是否可能优化代码,以便在锁定之前移动当前\u id的分配?

通常,编译器不应进行此类有害的优化。如果您仍然不确定,可以使用关键字来阻止对该id变量进行优化。

可以使用O3进行编译

除非函数被标记为纯使用函数属性,否则编译器永远不会在函数调用中进行优化


互斥函数不是纯粹的,因此与O3一起使用绝对安全。

volatile不会阻止所有相关的优化。它阻止值缓存在寄存器中,但几乎没有其他功能。读/写操作仍然可以重新排序。Linux内核文档中关于何时使用volatile的一个很好的处理方法:@jalf:但是编译器真的会重新排序读/写操作,以便它们跨越函数调用边界吗?赋值和函数调用混合在一起是很常见的,我想如果变量的赋值可以随函数调用切换顺序,那么会有很多问题。编译器可能会这样做(想象一下,如果它内联函数调用),但前提是它确定这样做是安全的。但是编译器在执行该分析时没有也不能考虑线程。它在一个执行线程内保留语义,但它可以并且将重新排序可能影响其他线程的读/写操作。即使编译器不这样做,CPU本身也会做同样的事情。确保读/写顺序的唯一方法是使用内存屏障。编译器和CPU都尊重这些。谢谢你更深入的解释,现在对我来说更清楚了:)你的意思是除非函数被标记为纯函数,或者编译器能够确定这样做是安全的。当然,最终的结果是一样的,编译器通常不会进行优化,除非它能够验证它是否安全。如果
current\u id
shared\u id
都是未超出当前范围的局部变量(地址没有给任何其他人,等等)然后优化器可以很好地重新排序这些行,而不考虑外部函数调用可能产生的变异。不过,我假设这里不是这样。@ephemient:但是如果它们是本地的,外部没有人知道它们,那么外部函数调用如何修改它们?@Kosi801:可能是通过堆栈上其他数据的缓冲区溢出或其他非法内存访问。这是不可移植的,也是错误的,但我见过人们尝试
inta,b;foo&a
其中
foo
写入
*&a
*(&a+1)
,假设它是
b