1
votes

Is it not possible to create two IPC shared memory segments from one process?

I am trying to create two shared memory from a single process one for sharing data with seperate process and other for shared with its child process. I am using shmget, i also tried to get the shared memory information in the system with ipcs. Output of which is something like this:

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x0beefbaf 0          root       666        225544     4                       
0x00000000 98305      root       666        4          0                       

Above output showed that two shared segment do get created, but shmget return only 0 as its output. Hence one shared memory segment is getting attached twice.

What is the problem with shmget or it is not possible to create two shared memory from one process.

1

1 Answers

1
votes

You're probably using the same key for the shared memory segment - if you want more than one shared memory segments then you need to use different keys. See the man page for ftok for the standard way of obtaining a key.

There are system level limits in place to prevent the use of too much memory - kernel.shmmax and the related sysctl properties.

This is a very simple example app that does exactly what the question asks:

#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);
}