我可以在C ++中使用互斥或​​关键字(静态)而不是volatile吗?

时间:2018-03-07 14:41:35

标签: c++ mutex volatile

我知道如何 volatile在C ++中有效。但是,我仍然对为什么我们需要不稳定感到困惑。我认为唯一的原因是我们需要监听变量是否发生变化,如下面的代码所示:

volatile int some_int = 100;

while(some_int==100) {
    doSomething()
}

程序员需要知道 some_int 这个词是否改变了,所以他使用“volatile”。我可以使用关键词“静态”吗?

大多数情况下,我认为如果多线程需要同步,我们应该互斥(锁定)同步。请原谅我可怜的英语:)

3 个答案:

答案 0 :(得分:5)

  

程序员需要知道some_int这个词是否改变了,所以他使用“volatile”。我可以使用关键词“静态”而不是

volatile在C ++ 98中用于并发编程,因为当时C ++不支持多线程作为语言,volatile的副作用有助于避免一些竞争条件,尽管有不保证它会/应该工作。从C ++ 11开始,有一些工具可以正确地使用并发编程 - std::mutexstd::atomic,所以你应该停止使用volatile用于错误的目的。变量static完全不相关,不会直接影响副作用的存在。

答案 1 :(得分:4)

  

volatile关键字旨在阻止编译器应用   对象的任何优化都可以以不可能的方式进行更改   由编译器确定。声明为volatile的对象被省略   来自优化,因为它们的值可以通过外部代码更改   任何时候当前代码的范围。   https://www.geeksforgeeks.org/understanding-volatile-qualifier-in-c/

作为一个长期嵌入式系统程序员,我的观点是volatile限定符是从我到编译器的“命令”。在逐个地址的基础上,我“命令”编译器始终执行每个访问I代码。编译器通过阻止某些代码优化来实现这一点。

  

为什么我们需要不稳定的

在内存映射的i / o(而不是端口i / o)中,我的代码处理来自硬件设备的反馈,表示例如“传输完成”,或“缓冲区已满”或“洛杉矶”(失信号)。每个人都有自己的紧迫感。

高度紧急通常会通过中断通知软件(并且几乎从不进行“轮询”,如您的示例所示)。硬件设计通常提供一些缓冲支持,使软件有更多时间来响应中断。在中断处理程序中,编译器不得优化任何硬件读取或写入。需要挥发性使用。

较低的紧急程度通常通过定期状态检查来处理(同样,永远不会通过轮询)。历史上,电信“los”每秒检查一次。这使软件能够在所需的2.5 +/- 0.5秒内(在洛杉矶启动后)报告系统警报。

绝不能跳过los-bit检查。关键字volatile命令编译器不删除执行检查的代码,无论软件最近看多少位。需要挥发性使用。

在这种情况下,信号量或原子不起作用......我所使用的硬件并不知道这些概念。需要挥发性。

  

我可以使用关键词“静态”吗?

没有

这是一项浪费的民意调查:

volatile int some_int = 100;

while(some_int==100) {
    doSomething()
}

永远不要这样做。

这是一个(大大简化)状态更新:

// status update thread 
do
{
    waitFor_startOfSecond();  // os provided call

    // status check
    if (los(bit))   // test the los bit in hw (1 of 10000)
    {
       losActions()
    }

    // ... other stuff, including other status bits

    // Note: expect less than 1 second elapsed since start of loop
    // On at least one system, this alarm processing effort 
    // completed in < 1/3 second  (even ~10,000 alarms)

} while(1); // typically, embedded threads do not halt

答案 2 :(得分:1)

  

大多数情况下,我认为如果在多线程中需要同步,我们应该互斥(锁定)同步。

你是对的。

而且,如果您有互斥锁,则不需要volatile(因为加载保证已经存在)。

  

程序员需要知道some_int这个词是否改变了,所以他使用&#34; volatile&#34;。

这是真的,或者至少它会是some_int而是由硬件或计算机的其他部分提供的某些值,而不是在程序的控制之下。您的程序无法判断何时此类值已在外部更改。

像:

volatile int* ptr_to_some_int = 0x0123456; // hardcoded address to somewhere magical!

printf("%d", *ptr_to_some_int); // okay, we'll get some value

// But the value of *ptr_to_some_int may have changed here...

printf("%d", *ptr_to_some_int); // ... so here it must be assuredly reloaded
  

我仍然对为什么我们需要挥发性感到困惑。

如果情况并非如此,那么你就不会。

  

我可以使用关键词&#34;静态&#34;代替?

不,static完全不相关。