我在多个进程之间有一个共享内存,它以某种方式对内存进行交互。前任:
DataBlock {
int counter;
double value1;
double ... }
我想要的是让计数器自动更新/递增。并在该地址上发生内存释放。例如,如果我没有使用共享内存,它将类似于
std::atomic<int> counter;
atomic_store(counter, newvalue, std::memory_order_release); // perform release operation on the affected memory location making the write visible to other threads
我如何为随机内存位置实现这一点(解释为上面的 DataBlock 计数器)?我可以保证地址按照架构(x86 Linux)的要求对齐。
- 使更新原子化 - 如何? (即
atomicupdate(addr, newvalue)
) - 多核的内存同步-(即
memorysync(addr)
)-我能看到的唯一方法是使用std::atomic_thread_fence(std::memory_order_release)
但这将“建立所有原子和宽松原子存储的内存同步排序”-就是这样对我来说有点矫枉过正——我只想同步计数器位置。欣赏任何想法。
原文由 excalibur 发布,翻译遵循 CC BY-SA 4.0 许可协议
我不能在这里权威地回答,但我可以提供可能有帮助的相关信息。
互斥锁可以在共享内存中创建和/或创建为跨进程。 Pthread 有一个特殊的创建标志,我不记得它是否使用共享内存,或者你共享一个句柄。 linux“futex”可以直接使用共享内存(注意用户地址可能不同,但底层真实地址应该相同)
硬件原子在内存而不是进程变量上工作。也就是说,您的芯片不会关心哪些程序正在修改变量,因此最低级别的原子自然会是跨进程的。这同样适用于栅栏。
C++11 未能指定跨进程原子。但是,如果它们是无锁的(检查标志),则很难看出编译器如何实现它们以使跨进程无法工作。但是您会非常信任您的工具链和最终平台。
CPU 依赖性保证还跟踪实际内存地址,因此只要您的程序在线程形式中是正确的,它在其多进程形式中也应该是正确的(关于可见性)。
Kerrek 是正确的,抽象机并没有真正提到多个进程。但是,它的同步细节以这样一种方式编写,即它们同样适用于进程间,就像它们适用于多线程一样。这与 #3 有关:编译器很难搞砸。
简短的回答,没有符合标准的方法来做到这一点。但是,根据标准定义多线程的方式,您可以为高质量的编译器做出很多假设。
最大的问题是是否可以简单地在共享内存中分配原子(放置新)并工作。显然,这只有在它是真正的硬件原子时才有效。然而,我的猜测是,使用高质量的编译器/库,C++ 原子应该可以在共享内存中找到。
玩得开心验证行为。 :)