2012-07-26 45 views
0

是否无法从一个进程创建两个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有什么问题,或者无法从一个进程创建两个共享内存。

回答

0

您可能对共享内存段使用了相同的密钥 - 如果您需要多个共享内存段,则需要使用不同的密钥。获取钥匙的标准方式,请参见手册页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); 
} 
+0

感谢您的答复,但我可以看到IPCS 2个共享内存段。共享内存ID为0,其数量大于/ proc/sys/kernel/shmmni(4096)。我不知道为什么第二个共享内存获得的数字大于4096,即使在创建了segement之后,它也会返回相同的id,即0,即第一个段的ID。顺便说一下,共享内存的要求比shmmax和shmall要低。 – sujitKN 2012-07-27 07:01:19

+0

当您创建/访问共享内存段时,第一个参数是一个键。如果您使用相同的值作为密钥,那么您将访问相同的共享内存段。该ID与分段数量的限制无关 - 这是并行分段数量的限制。使用ftok的原因是,它允许基于现有文件的密钥的唯一规范 - 原始算法使用inode编号作为密钥的种子。 – Petesh 2012-07-27 07:56:05

+0

是Petesh,我已经使用两个独立的密钥进行两个共享内存配置,因为对shmget的这两个调用都创建不同的共享内存段,但返回相同的ID。 – sujitKN 2012-07-27 09:35:55

相关问题