带有函数访问的全局共享变量的 C++ volatile 关键字

标签 c++ multithreading concurrency volatile

我有一个多线程 C++ 应用程序。

现在我知道对于全局共享变量,在某些情况下您应该在检查变量状态时使用 volatile,否则编译器可能会假设变量的值永远不会改变(在该线程中)。

但是,如果我没有检查变量的状态,而是调用了一个返回变量值的方法,会怎样呢?例如:

static int num = 0;

...

void foo()
{
   while(getNum() == 0)
   {
      // do something (or nothing)
   }
}

我还需要将 num 设置为可变变量吗?或者编译器是否认识到,因为我正在使用一种方法来访问该变量 num,所以它不会缓存结果?

有人有什么想法吗?

提前致谢

~朱利安

编辑:在我的 while 循环中,我删除了 sleep 调用并将其替换为一些通用的东西,例如做某事(或什么都不做)的评论

最佳答案

不,只要您进行必要的同步,就永远不需要 volatile

调用线程库同步函数,无论它们在您的平台上是什么,都应该注意使本地“缓存”值无效并使编译器重新加载全局变量。

在这种特殊情况下,sleep 很可能会产生这样的效果,但无论如何这都不是一个好的实现。 num 上应该有一个条件变量,用 setter 函数保护它,并让 setter 函数向 foo 发送信号。

至于具体问题,该函数是否隐藏了优化的访问权限是非常依赖于实现和情况的。最好的办法是在编译器的单独调用中编译 getter 函数,但即便如此,也无法保证不会发生过程间优化。例如,某些平台可能会将IR代码放在.o文件中,并在“链接器”阶段进行代码生成。

免责声明。

上面的关键词:1.只要你在做必要的同步和2.可能有这样的效果

1:sleep 或空的忙循环不是“必要的同步”。这不是编写多线程程序的正确方法,句号。因此,在这种情况下可能需要 volatile。

2: 是的,sleep 可能不计入 I/O 函数的实现,甚至可能被标记为纯净且无副作用。在这种情况下,全局的 volatile 将是必要的。但是,我怀疑是否真的分发了任何会破坏 sleep 循环的实现,因为不幸的是它们很常见。

关于带有函数访问的全局共享变量的 C++ volatile 关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3650267/

相关文章:

c++ - Clion 退出代码 -1073741571 (0xC00000FD)

c++ - 如何从父模板函数访问子成员?

java - 工作线程到工作线程通信

eclipse - SSH(FTP)和Web服务器并发文件IO

linux - 路径查找和写入并发问题

c++ - Visual Studio 2015 rc中从模板类派生的类的构造函数继承

c++ - C++03 中的模板函数返回类型推导

java - 多线程应用程序中编译时和运行时类路径不匹配的原因是什么?

c++ - 如何实现单个消息的消息传递?

sql - 使用 SQL Server 作为具有多个客户端的数据库队列