Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.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++ 通过中断修改常量引用_C++ - Fatal编程技术网

C++ 通过中断修改常量引用

C++ 通过中断修改常量引用,c++,C++,外部修改const引用传递的变量(通过中断)安全吗 这里我们有一个常量引用,它是通过中断在外部修改的。我得到一个事实,被调用方(方法)不能修改标志,但是调用方可以修改g?因为在g空间std::atomic\u bool不是常量。如果这是一个正在更改标志的外部进程/OS,那么您只需要原子,仅此而已,不需要volatile。这就是SIGHUP的情况 如果这是改变值的实际硬件中断:这是volatile关键字的极少数有效用例之一。(非常)笼统地说,volatile通知编译器,它不能假设最后写入地址的值将

外部修改const引用传递的变量(通过中断)安全吗


这里我们有一个常量引用,它是通过中断在外部修改的。我得到一个事实,被调用方(
方法
)不能修改
标志
,但是调用方可以修改
g
?因为在
g
空间
std::atomic\u bool
不是常量。

如果这是一个正在更改标志的外部进程/OS,那么您只需要原子,仅此而已,不需要
volatile
。这就是SIGHUP的情况


如果这是改变值的实际硬件中断:这是
volatile
关键字的极少数有效用例之一。(非常)笼统地说,
volatile
通知编译器,它不能假设最后写入地址的值将是从地址读取的值,或者不写入地址的值不会改变。在本例中,您有一个
常量volatile std::atomic\u bool&
——在本例中,将
g
本身声明为
volatile
和atomic。

如果这是一个正在更改标志的外部进程/OS,那么您只需要atomic,仅此而已,不需要
volatile
。这就是SIGHUP的情况


如果这是改变值的实际硬件中断:这是
volatile
关键字的极少数有效用例之一。(非常)笼统地说,
volatile
通知编译器,它不能假设最后写入地址的值将是从地址读取的值,或者不写入地址的值不会改变。在本例中,您有一个
常量volatile std::atomic\u bool&
——在本例中,将
g
本身声明为
volatile
和atomic。

我不同意这里的@lorro。你不需要挥发性修饰语

std::atomic::operator

以原子方式加载并返回原子变量的当前值。 等效于load()

这意味着每次在循环条件中计算
标志
时,您都会自动获得标志变量的实际值。您不必将此变量标记为volatile


Scott Meyers
有效现代C++
章节
项目40: 使用std::atomic实现并发,volatile实现特殊内存

我不同意@loro的说法。你不需要挥发性修饰语

std::atomic::operator

以原子方式加载并返回原子变量的当前值。 等效于load()

这意味着每次在循环条件中计算
标志
时,您都会自动获得标志变量的实际值。您不必将此变量标记为volatile


Scott Meyers
有效现代C++
章节
项目40: 将std::atomic用于并发,volatile用于特殊内存

明智的做法是将
g
声明为
volatile std::atomic_bool
,以保证代码中其他地方的波动性。@NikitaKakuev:在答案中加入您的注释,谢谢。最好将
g
声明为
volatile std::atomic_bool
,以保证代码中其他地方的波动性。@NikitaKakuev:在回答中加入您的评论,谢谢。您不必同意:),但当中断直接修改内存值时,它怎么不是特殊内存呢?如果允许任务继续然后写入的并发任务类中断触发事件修改了该值,则您的注释有效。当一个内存地址被硬件从外部修改时,为什么它不是特定的内存呢?不是说它是最好的源,但MSDN将volatile定义为:“一个类型限定符,可以用来声明一个对象可以在程序中被硬件修改。”另外:@lorro,你在说什么硬件中断?主题启动示例考虑UNIX信号中断,它与硬件中断没有任何共同之处。变量g由来自同一处理器但在不同堆栈/CPU上下文上的代码修改。volatile在这里绝对不是一个例子。@user1631854:OP写“外部修改(通过中断)”,但随后给出了一个已修改的示例。这些是相互矛盾的。前者需要
易失性
,后者只需要原子性。编辑我的帖子以澄清这一点。你不必同意:),但是当一个中断直接修改内存值时,它怎么不是特殊内存呢?如果允许任务继续然后写入的并发任务类中断触发事件修改了该值,则您的注释有效。当一个内存地址被硬件从外部修改时,为什么它不是特定的内存呢?不是说它是最好的源,但MSDN将volatile定义为:“一个类型限定符,可以用来声明一个对象可以在程序中被硬件修改。”另外:@lorro,你在说什么硬件中断?主题启动示例考虑UNIX信号中断,它与硬件中断没有任何共同之处。变量g由来自同一处理器但在不同堆栈/CPU上下文上的代码修改。volatile在这里绝对不是一个例子。@user1631854:OP写“外部修改(通过中断)”,但随后给出了一个已修改的示例。这些是相互矛盾的。前者需要
易失性
,后者只需要原子性。编辑我的文章,让这一点更清楚。
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