Linux 内核中的 shmat() 等是如何实现的。还有其他共享内存的方法吗?

How is shmat() etc. implemented in the Linux kernel. Is there any other way to share memory?

mmap() 一样,进程必须从父进程继承映射才能共享内存。有没有办法在不共享父进程的进程之间共享内存? shmat() 似乎是最好的解决方案,但如果进程未分离 exit/die 上的内存,则需要进行清理。

域套接字即将共享内存...

对于 mmap,如果您使用匿名内存,进程必须从父进程继承映射。但是,如果映射由文件支持,则没有这样的要求。 shmat,又名 System V 共享内存,也不是没有问题 - 传统上它曾经是一种有限的资源,需要使用 sysctl 和 root 来提高限制。

使用 mmap 两个进程可以打开和映射同一个文件,然后 取消链接文件。现在,当所有进程退出时,该文件也将被自动删除。或者它可以在开始时取消链接 - 服务器进程然后可以通过 unix 套接字将打开的文件描述符共享给客户端。

当然,使用带文件支持的 mmap 意味着您将需要实际磁盘 space 来支持映射,映射将被刷新到磁盘。

如果你想要一个没有磁盘文件支持的映射,你可以使用POSIX shared memory objects:

System V shared memory (shmget(2), shmop(2), etc.) is an older shared memory API. POSIX shared memory provides a simpler, and better designed interface; on the other hand POSIX shared memory is somewhat less widely available (especially on older systems) than System V shared memory.

在 Linux 上,这些本质上只是 /dev/shm 中的文件,但使用这些文件的可移植方式是使用 shm_open 创建和打开它们。同样,即使共享内存对象未与 shm_unlink 链接,打开共享内存对象的进程也可以通过 unix 域套接字向其发送打开的文件描述符,并且接收方可以使用描述符映射共享内存进入它的进程 space.

因此类似于:

fd = shm_open("/my_shared_mem", O_RDWR|O_CREAT, 0700);
ftruncate(fd, 64 * 4096);
shared_mem = mmap(NULL, 64 * 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)

在第一个过程中,第二个可以用O_RDWR打开,不需要截断。要删除共享内存对象,请使用 shm_unlink:

shm_unlink("/my_shared_mem");

这将立即取消它与 /dev/shm 的链接;那些打开它的进程可以继续使用它;该对象实际上仅在每个进程停止使用它时才被删除。