在共享内存上使用 volatile 安全吗?

Nic*_*ick 3 c++ volatile shared-memory stdatomic

让我们假设如下:

我在 Linux / Mac OS 上有两个进程。

我有mmap共享内存(或在文件中)。

然后在这两个过程中我都有以下内容:

struct Data{
   volatile int reload = 0; // using int because is more standard
   // more things in the future...
};
void *mmap_memory = mmap(...);
Data *data = static_cast<Data *>(mmap_memory); // suppose size is sufficient and all OK
Run Code Online (Sandbox Code Playgroud)

然后在我做的其中一个过程中:

//...
data->reload = 1;
//...
Run Code Online (Sandbox Code Playgroud)

在另一个我做的:

while(...){
    do_some_work();
    //...
    if (data->reload == 1)
        do_reload();
}
Run Code Online (Sandbox Code Playgroud)

这会是线程/进程间安全的吗?

想法来自这里:
https://embeddedartistry.com/blog/2019/03/11/improve-volatile-usage-with-volatile_load-and-volatile_store/

注意:
这对于 来说并不安全std::atomic<>,因为它不“承诺”有关共享内存的任何内容。此外,从两个不同的过程构建/销毁根本不清楚。

And*_*nle 5

\n

这会是线程/进程间安全的吗?

\n
\n

不。

\n

从您自己的链接

\n
\n

一个有问题且常见的假设是 volatile 相当于 \xe2\x80\x9catomic\xe2\x80\x9d。不是这种情况。挥发性关键字仅表示该变量可以在外部修改,因此无法优化读/写。

\n
\n

您的代码需要对该值进行 原子访问。if (data->reload == 1)如果它从 读取一些部分/中间值,则将无法工作data->reload

\n

并且不要介意如果多个线程确实读取会1发生什么data->reload- 您发布的代码根本无法处理该问题。

\n

另请参阅为什么 volatile 在多线程 C 或 C++ 编程中不被认为有用?

\n