从shm_open()+ mmap()更改为共享内存的可见性 [英] Visibility of change to shared memory from shm_open() + mmap()

查看:93
本文介绍了从shm_open()+ mmap()更改为共享内存的可见性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我使用的是CentOS 7 x86_64 + GCC 7.

Let's say I am on CentOS 7 x86_64 + GCC 7.

我想在共享内存中创建一个环形缓冲区.

I would like to create a ringbuffer in shared memory.

如果我有两个过程Producer和Consumer,并且它们都共享一个命名的共享内存,则该共享内存是通过shm_open()+ mmap()创建/访问的.

If I have two processes Producer and Consumer, and both share a named shared memory, which is created/accessed through shm_open() + mmap().

如果Producer编写如下内容:

If Producer writes something like:

struct Data {
uint64_t length;
char data[100];
}

随机访问共享内存,并且使用者不断轮询共享内存以进行读取.我会遇到某种同步问题,即看到成员长度但成员数据仍在写入过程中吗?如果是,那么避免该问题的最有效方法是什么?

to the shared memory at a random time, and the Consumer is constantly polling the shared memory to read. Will I have some sort of synchronization issue that the member length is seen but the member data is still in the progress of writing? If yes, what's the most efficient technique to avoid the issue?

我看到这篇文章:共享内存IPC同步(无锁)

但是我想更深入,更简单地了解在两个流程之间进行有效同步所需的内容.

But I would like to get a deeper, more low level of understanding what's required to synchronize between two processes efficiently.

提前谢谢!

推荐答案

为避免这种情况,您需要构建结构 std :: atomic 并以获取释放内存的顺序对其进行访问.在大多数现代处理器上,此插入的指令是内存隔离区,可确保写入器在开始写入之前等待所有加载完成,并确保读取器在开始读取之前等待所有存储完成.

To avoid this, you would want to make the structure std::atomic and access it with acquire-release memory ordering. On most modern processors, the instructions this inserts are memory fences, which guarantee that the writer wait for all loads to complete before it begins writing, and that the reader wait for all stores to complete before it begins reading.

此外,POSIX中还锁定了基元,但是< atomic> 标头是较新的,并且可能是您想要的.

There are, in addition, locking primitives in POSIX, but the <atomic> header is newer and what you probably want.

在[atomics.lockfree]中,添加了重点:

From [atomics.lockfree], emphasis added:

无锁的操作也应无地址.也就是说,通过两个不同的地址对同一内存位置进行的原子操作将进行原子通信.实现不应依赖于任何每个进程的状态.此限制允许通过多次映射到一个进程的内存以及在两个进程之间共享的内存进行通信.

对于可锁定原子,标准在[thread.rec.lockable.general]中指出,重点是:

For lockable atomics, the standard says in [thread.rec.lockable.general], emphasis added:

执行代理是一个实体,例如可以与其他执行代理并行执行工作的线程.[...]实现或用户可能会引入其他种类的代理诸如流程 [....]

您有时会看到这样的说法,即该标准没有提及使用< atomic> 原语,而原语仅在线程之间共享,而在进程之间共享内存.这是不正确的.

You will sometimes see the claim that the standard supposedly makes no mention of using the <atomic> primitives with memory shared between processes, only threads. This is incorrect.

但是,通过共享内存传递指向另一个进程的指针将不起作用,因为共享内存可能被映射到地址空间的不同部分,并且当然,指向不在共享内存中的任何对象的指针都是正确的.共享内存中对象的索引和偏移量.(或者,如果您确实需要指针,Boost提供IPC安全的包装器.)

However, passing pointers to the other process through shared memory will not work, as the shared memory may be mapped to different parts of the address space, and of course a pointer to any object not in shared memory is right out. Indices and offsets of objects within shared memory will. (Or, if you really need pointers, Boost provides IPC-safe wrappers.)

这篇关于从shm_open()+ mmap()更改为共享内存的可见性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆