通过中断

时间:2016-07-08 18:01:41

标签: c++

通过外部(通过中断)修改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不是常量。

2 个答案:

答案 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类型之间的区别。