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

时间:2011-11-16 15:46:33

标签: c++ posix shared-memory

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

我以前从未处理过共享内存。更糟糕的是,我是C ++和POSIX的新手。有人可以提供一些指导吗?非常感谢简单的例子。

1 个答案:

答案 0 :(得分:0)

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(普通旧数据),则通过shmem共享对象是最简单的。没什么好看的。

因为您处于不共享整个地址空间的不同进程中,所以可能无法保证虚拟函数之类的东西将出现在使用shm共享内存段的所有进程中的同一地址。所以最好避免使用虚函数。 (如果你努力和/或知道链接,你可能在某些情况下能够共享虚函数。但如果我不得不调试,这是我要禁用的第一件事。)

如果您了解实现的对象内存模型,则应该只执行此操作。如果高级(对于C ++)优化,例如将结构拆分为不连续的冷热部分则被禁用。由于这种优化可能对C ++来说不合法,所以你可能很安全。

如果你在所有方面都投射到相同的对象类型/类,显然你会更好。 你可以逃脱非虚拟功能。但是,请注意,拥有相同的类可以很容易,但是类的不同版本 - 例如尺寸不同,例如添加一个新字段并更改所有其他字段的偏移量 - 因此您需要非常小心以确保所有方使用相同的定义和声明。