对共享内存的原子访问

新手上路,请多包涵

我在多个进程之间有一个共享内存,它以某种方式对内存进行交互。前任:

 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)的要求对齐。

  1. 使更新原子化 - 如何? (即 atomicupdate(addr, newvalue)
  2. 多核的内存同步-(即 memorysync(addr) )-我能看到的唯一方法是使用 std::atomic_thread_fence(std::memory_order_release) 但这将“建立所有原子和宽松原子存储的内存同步排序”-就是这样对我来说有点矫枉过正——我只想同步计数器位置。欣赏任何想法。

原文由 excalibur 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
1 个回答

我不能在这里权威地回答,但我可以提供可能有帮助的相关信息。

  1. 互斥锁可以在共享内存中创建和/或创建为跨进程。 Pthread 有一个特殊的创建标志,我不记得它是否使用共享内存,或者你共享一个句柄。 linux“futex”可以直接使用共享内存(注意用户地址可能不同,但底层真实地址应该相同)

  2. 硬件原子在内存而不是进程变量上工作。也就是说,您的芯片不会关心哪些程序正在修改变量,因此最低级别的原子自然会是跨进程的。这同样适用于栅栏。

  3. C++11 未能指定跨进程原子。但是,如果它们是无锁的(检查标志),则很难看出编译器如何实现它们以使跨进程无法工作。但是您会非常信任您的工具链和最终平台。

  4. CPU 依赖性保证还跟踪实际内存地址,因此只要您的程序在线程形式中是正确的,它在其多进程形式中也应该是正确的(关于可见性)。

  5. Kerrek 是正确的,抽象机并没有真正提到多个进程。但是,它的同步细节以这样一种方式编写,即它们同样适用于进程间,就像它们适用于多线程一样。这与 #3 有关:编译器很难搞砸。

简短的回答,没有符合标准的方法来做到这一点。但是,根据标准定义多线程的方式,您可以为高质量的编译器做出很多假设。

最大的问题是是否可以简单地在共享内存中分配原子(放置新)并工作。显然,这只有在它是真正的硬件原子时才有效。然而,我的猜测是,使用高质量的编译器/库,C++ 原子应该可以在共享内存中找到。

玩得开心验证行为。 :)

原文由 edA-qa mort-ora-y 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题