通过外部(通过中断)修改const引用传递的变量是否安全?
std::atomic_bool g(true);
void sig_handler(int num) {
switch(num) {
case SIGHUP:
g = false;
break;
}
}
void method(const std::atomic_bool &flag) {
while(flag) {
...
}
}
method(g); // blocks
这里我们有一个const引用,通过中断在外部修改。我得到被调用者(method
)无法修改flag
的事实,但调用者是否可以修改g
?因为在g
空间std::atomic_bool
不是常量。
答案 0 :(得分:2)
如果这是一个正在改变标志的外部进程/操作系统,那么你只需要原子,就是全部,不需要volatile
。这是SIGHUP的情况。
如果这是更改值的实际硬件中断:这是volatile
关键字的极少数有效用例之一。 (非常)松散地说,volatile
通知编译器它不能假定写入最后一个地址的值将是从地址读取的值,或者如果没有写入它就不会改变该值。在这种情况下,您有const volatile std::atomic_bool&
- 在这种情况下,将g
本身声明为volatile
和原子。
答案 1 :(得分:0)
我不同意@lorro的意见。你真的不需要挥发性修饰剂。
std::atomic<T>::operator<T>
:
以原子方式加载并返回原子变量的当前值。 相当于load()。
这意味着每次在循环条件中评估flag
时,您原子地获得flag变量的实际值。而且你不必将这个变量标记为易变。
在迈克尔迈耶斯Effective Modern C++
章节Item 40: Use std::atomic for concurrency, volatile for special memory
中完美地解释了volatile和std :: atomic类型之间的区别。