访问共享内存 C++ 中的数据POSIX
我打开一块共享内存并获取它的句柄。我知道内存中存储了多个数据向量。我想访问这些数据向量并对它们执行一些操作。我怎样才能实现这个目标?将共享内存视为一个对象是否合适,以便我们可以将这些向量定义为该对象的字段,并将那些所需的操作定义为该对象的成员函数?
我以前从未处理过共享内存。更糟糕的是,我是 C++ 和 POSIX 的新手。有人可以提供一些指导吗?简单的例子将不胜感激。
I open a piece of shared memory and get a handle of it. I'm aware there are several vectors of data stored in the memory. I'd like to access those vectors of data and perform some actions on them. How can I achieve this? Is it appropriate to treat the shared memory as an object so that we can define those vectors as fields of the object and those needed actions as member functions of the object?
I've never dealt with shared memory before. To make things worse, I'm new to C++ and POSIX. Could someone please provide some guidance? Simple examples would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
...或者,在您安排传递
address_of_my_shm1
的其他线程/进程中...通过其他方式
您可能想要断言
address_of_shm1 == address_of_shm2
。但请注意,我说的是“可以”——您实际上不必这样做。某些类型/结构/类可以在不同地址同样良好地读取。如果对象出现在不同的地址空间中,那么进程A中shm之外的指针可能不会指向与进程B中相同的东西。一般来说,shm之外的指针是不好的。 (虚拟函数是对象外部和 shm 外部的指针。不好,除非您有其他理由信任它们。)
如果 shm 内部的指针出现在同一地址,则它们是可用的。
相对指针非常有用,但是,只要它们仅指向 shm 内部。相对指针可以相对于对象的基址,即它们可以是偏移量。或者它们可能与指针本身相关。您可以定义一些不错的类/模板来执行这些计算,并在幕后进行转换。
如果数据只是 POD(普通旧数据),则通过 shmem 共享对象是最简单的。没什么花哨的。
因为您位于不共享整个地址空间的不同进程中,所以您可能无法保证诸如虚拟函数之类的内容会出现在使用 shm 共享内存段的所有进程中的同一地址处。所以最好避免虚拟函数。 (如果您努力尝试和/或了解链接,在某些情况下您可能能够共享虚拟函数。但如果我必须调试,这是我首先要禁用的事情之一。)
只有在您知道的情况下才应该这样做您的实现的对象内存模型。如果高级(对于 C++)优化(例如将结构拆分为不连续的热部分和冷部分)被禁用。由于此类优化对于 C++ 来说可能不合法,因此您可能是安全的。
显然,如果您在所有方面都转换为相同的对象类型/类,情况会更好。
您可以摆脱非虚拟函数。但是,请注意,拥有相同的类但该类的不同版本可能非常容易 - 例如大小不同,例如添加新字段并更改所有其他字段的偏移量 - 因此您需要非常小心确保各方使用相同的定义和声明。
...or, in some other thread/process to which you arranged to pass the
address_of_my_shm1
...by some other means
You may want to assert that
address_of_shm1 == address_of_shm2
. But note that I say "may" - you don't actually have to do this. Some types/structs/classes can be read equally well at different addresses.If the object will appear in different address spaces, then pointers outside the shhm in process A may not point to the same thing as in process B. In general, pointers outside the shm are bad. (Virtual functions are pointers outside the object, and outside the shm. Bad, unless you have other reason to trust them.)
Pointers inside the shm are usable, if they appear at the same address.
Relative pointers can be quite usable, but, again, so long as they point only inside the shm. Relative pointers may be relative to the base of an object, i.e. they may be offsets. Or they may be relative to the pointer itself. You can define some nice classes/templates that do these calculations, with casting going on under the hood.
Sharing of objects through shmem is simplest if the data is just POD (Plain Old Data). Nothing fancy.
Because you are in different processes that are not sharing the whole address space, you may not be guaranteed that things like virtual functions will appear at the same address in all processes using the shm shared memory segment. So probably best to avoid virtual functions. (If you try hard and/or know linkage, you may in some circumstances be able to share virtual functions. But that is one of the first things I would disable if I had to debug.)
You should only do this if you are aware of your implementation's object memory model. And if advanced (for C++) optimizations like splitting structs into discontiguous hot and cold parts are disabled. Since such optimizations rae arguably not legal for C++, you are probably safe.
Obviously you are better off if you are casting to the same object type/class on all sides.
You can get away with non-virtual functions. However, note that it can be quite easy to have the same class, but different versions of the class - e.g. differing in size, e.g. adding a new field and changing the offsets of all of the other fields - so you need to be quite careful to ensure all sides are using the same definitions and declarations.