从一个进程创建多个共享内存
Posted
技术标签:
【中文标题】从一个进程创建多个共享内存【英文标题】:Multiple shared memory creation from one process 【发布时间】:2012-07-26 12:52:10 【问题描述】:一个进程不能创建两个IPC共享内存段吗?
我正在尝试从一个进程创建两个共享内存,一个用于与单独的进程共享数据,另一个用于与其子进程共享。我正在使用shmget,我也尝试使用ipcs获取系统中的共享内存信息。其输出是这样的:
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x0beefbaf 0 root 666 225544 4
0x00000000 98305 root 666 4 0
以上输出显示确实创建了两个共享段,但 shmget 仅返回 0 作为其输出。因此,一个共享内存段被附加了两次。
shmget 有什么问题,或者无法从一个进程创建两个共享内存。
【问题讨论】:
【参考方案1】:您可能对共享内存段使用相同的密钥 - 如果您想要多个共享内存段,那么您需要使用不同的密钥。有关获取密钥的标准方法,请参见 ftok
的手册页。
存在系统级别限制以防止使用过多内存 - kernel.shmmax
和相关的 sysctl 属性。
这是一个非常简单的示例应用程序,它完全按照问题的要求:
#include <sys/shm.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
int main(int argc, char **argv)
key_t key1;
key_t key2;
if (-1 != open("/tmp/foo", O_CREAT, 0777))
key1 = ftok("/tmp/foo", 0);
else
perror("open");
exit(1);
if (-1 != open("/tmp/foo2", O_CREAT, 0777))
key2 = ftok("/tmp/foo2", 0);
else
perror("open");
exit(1);
printf("%x %x\n", key1, key2);
int id1 = shmget(key1, 0x1000, IPC_CREAT | SHM_R | SHM_W);
int id2 = shmget(key2, 0x2000, IPC_CREAT | SHM_R | SHM_W);
printf("%x %x\n", id1, id2);
void *addr1 = shmat(id1, 0, 0);
if (addr1 == (void *)-1) perror("shmat1");
void *addr2 = shmat(id2, 0, 0);
if (addr2 == (void *)-1) perror("shmat2");
printf("%p %p\n", addr1, addr2);
shmctl(id1, IPC_RMID, NULL);
shmctl(id2, IPC_RMID, NULL);
【讨论】:
感谢您的回复,但我可以看到 2 与 ipcs 共享内存段。共享内存 id 是 0 和一个大于 /proc/sys/kernel/shmmni (4096) 的数字。我不知道为什么第二个共享内存的数字大于 4096,即使在创建了两个段之后,它也会为两个段返回相同的 id,即 0 是第一个段的 ID。顺便说一下,共享内存的要求比 shmmax 和 shmall 低很多。 当你创建/访问一个共享内存段时,第一个参数是一个键。如果您对键使用相同的值,那么您将访问相同的共享内存段。 ID 与段数的限制无关 - 它用于并发段数。使用 ftok 的原因是它允许基于现有文件的密钥的唯一规范 - 原始算法使用 inode 号作为密钥的种子。 是的,Petesh,我为两个共享内存配置使用了两个单独的键,因为对 shmget 的调用都创建了不同的共享内存段,但返回了相同的 id。 对不起,我发现了问题并纠正了。感谢您的宝贵时间和帮助。以上是关于从一个进程创建多个共享内存的主要内容,如果未能解决你的问题,请参考以下文章