访问共享内存中的数据c++ POSIX

Access data in shared memory C++ POSIX

本文关键字:c++ POSIX 数据 内存 访问共享      更新时间:2023-10-16

我打开一块共享内存并获得它的句柄。我知道内存中存储了几个数据向量。我想访问这些数据向量并对它们执行一些操作。我怎样才能做到这一点呢?是否适合将共享内存视为对象,以便我们可以将这些向量定义为对象的字段,并将所需的操作定义为对象的成员函数?

我以前从未处理过共享内存。更糟糕的是,我是c++和POSIX的新手。有人能给我一些指导吗?简单的例子将不胜感激。

int my_shmid = shmget(key,size,shmflgs);
...
void* address_of_my_shm1 = shat(my_shmid,0,shmflags);
Object* optr = static_cast<Object*>(address_of_my_shm1);

…或者,在您安排传递address_of_my_shm1的其他线程/进程中…通过其他方式

void* address_of_my_shm2 = shat(my_shmid,address_of_my_shm1,shmflags);

您可能想断言address_of_shm1 == address_of_shm2。但请注意,我说的是"可能"——你实际上不必这样做。有些类型/结构/类可以在不同的地址读得同样好。

如果对象将出现在不同的地址空间中,那么进程A中的shhm之外的指针可能与进程b中的指针指向不同的对象。通常,shm之外的指针是不好的。(虚函数是对象之外和shm之外的指针。不好,除非你有其他理由相信他们。

shm中的指针是可用的,如果它们出现在同一个地址。

相对指针可以非常有用,但是,同样,只要它们只指向shm内部。相对指针可以相对于对象的基底,也就是说,它们可以是偏移量。或者它们可能相对于指针本身。你可以定义一些很好的类/模板来做这些计算,在底层进行强制转换。

如果数据只是POD (Plain Old data),那么通过shmem共享对象是最简单的。没有什么幻想。

因为您在不同的进程中,这些进程没有共享整个地址空间,所以您可能无法保证像虚拟函数这样的东西在使用shm共享内存段的所有进程中出现在相同的地址上。所以最好避免使用虚函数。(如果您努力尝试并且/或知道链接,您可能在某些情况下能够共享虚拟函数。但是,如果我必须调试,这是我首先要禁用的东西之一。

如果你知道你的实现的对象内存模型,你应该只这样做。如果高级优化(针对c++)被禁用,比如将结构体拆分为不连续的热部分和冷部分。因为这样的优化在c++中是不合法的,所以你可能是安全的。

显然,如果你在所有方面都转换为相同的对象类型/类,你会更好。你可以使用非虚函数。但是,请注意,拥有相同的类,但拥有不同版本的类是很容易的——例如大小不同,例如添加新字段并更改所有其他字段的偏移量——因此您需要非常小心地确保所有方面都使用相同的定义和声明。