我知道如何 volatile在C ++中有效。但是,我仍然对为什么我们需要不稳定感到困惑。我认为唯一的原因是我们需要监听变量是否发生变化,如下面的代码所示:
volatile int some_int = 100;
while(some_int==100) {
doSomething()
}
程序员需要知道 some_int 这个词是否改变了,所以他使用“volatile”。我可以使用关键词“静态”吗?
大多数情况下,我认为如果多线程需要同步,我们应该互斥(锁定)同步。请原谅我可怜的英语:)
答案 0 :(得分:5)
程序员需要知道some_int这个词是否改变了,所以他使用“volatile”。我可以使用关键词“静态”而不是
volatile
在C ++ 98中用于并发编程,因为当时C ++不支持多线程作为语言,volatile
的副作用有助于避免一些竞争条件,尽管有不保证它会/应该工作。从C ++ 11开始,有一些工具可以正确地使用并发编程 - std::mutex
和std::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
完全不相关。