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