Reputation: 21
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.
Upvotes: 1
Views: 5004
Reputation: 11
I was facing similar kind of issue and got fixed by removing ftok() function for creating key. Instead I manually gave value as key.
Eg :
key_t key = ftok("shmfile", 65);
( Old)
key_t key = 1234;
( Modified )
This fixed my issue :)
Upvotes: 0
Reputation: 94869
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);
}
Upvotes: 1