I'm on Linux 2.6 and I have a weird problem. I have 3 concurrent processes (forked from the same process) which need to obtain 3 DIFFERENT shared memory segments, one for each process. Each of the process executes this code (please note that 'message' type is user-defined)
message *m;
int fd = shm_open("message", O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
ftruncate(fd, sizeof(message));
m = mmap(NULL, sizeof(message), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
char messagename[16];
snprintf(messagename, sizeof(messagename), "%p", m);
char path[32] = "/dev/shm/";
strcat(path, messagename);
rename("/dev/shm/message", path);
Let me explain a bit: I want every process to allocate a shared memory zone which contains a message. To make sure another process (the message receiver) can access the same shm, I then rename my shm file from "message" to a string named after the message pointer (this because the process which receives the message already knows the pointer).
When executing the program, though, I tried to print (for debugging purpose) the pointers that every process received when mmapping the fd obtained with shm_open, and I noticed that all of them got the SAME pointer. How is it possible? I thought that maybe other processes did the shm_open() after the first one did and before it renamed the segment, so I also tried to make these lines of code an atomic operation by using a process shared mutex, but the problem persists.
I would really appreciate any kind of help or suggestion.
Your processes all started with identical address space layouts at the moment of forking, and then followed very similar code paths. It is therefore not surprising that they all end up with the same value of
m
.However, once they became separate processes, their address spaces became independent, so having the same value of
m
does not imply that all of them
s are pointing to the same thing.Furthermore, I am not sure that your idea of renaming the
/dev/shm
entry after creating the shared memory block is safe or portable. If you want each process's shared memory block to have a unique name, why not base the name on the process ID (which is guaranteed to be unique at a given point in time) and pass it directly to shm_open, rather than going to the bother of renaming it afterwards?