Mmap and structure
I am working on some code including inter-process communication using semaphores. I created a structure like this:
typedef struct container {
sem_t resource, mutex;
int counter;
} container;
and use that way (in the main application and in the subprocesses)
container *memory;
shm_unlink("MYSHM"); //just in case
fd = shm_open("MYSHM", O_RDWR|O_CREAT|O_EXCL, 0);
if(fd == -1) {
printf("Error");
exit(EXIT_FAILURE);
}
memory = mmap(NULL, sizeof(container), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
ftruncate(fd, sizeof(container));
Everything is fine when I use one of the sem_ functions, but when I try to do something like
memory->counter = 5;
This does not work. I guess I have something wrong with pointers, but I tried almost everything and nothing works. Maybe there is a better way to exchange variables, structures, etc. Between processes? Unfortunately I am not allowed to use boost or anything similar, the code is for educational purposes and I intend to keep things as simple as possible.
a source to share
Since you are using shm_unlink()
just before shm_open()
, your two processes never open the same shared memory object - each creates a new, separate object (although it has the same name).
It is not clear what you mean by "not working". The following minimal example based on your code works great for me. What does he do for you?
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <semaphore.h>
typedef struct container {
sem_t resource, mutex;
int counter;
} container;
int main()
{
container *memory;
int fd = shm_open("MYSHM", O_RDWR|O_CREAT|O_EXCL, 0);
if(fd == -1) {
perror("shm_open");
return 1;
}
ftruncate(fd, sizeof(container));
memory = mmap(NULL, sizeof(container), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
memory->counter = 5;
printf("%d\n", memory->counter);
return 0;
}
When looking at the code, it doesn't work because you are trying to access the file descriptor in the child process after exec()
, and shm_open
by default sets a flag FD_CLOEXEC
so that the file descriptor is no longer opened in the child. Therefore, you just need to disable this flag in the main process (for example, right after checking the error after shm_open
):
fdflags = fcntl(fd, F_GETFD); fdflags &= ~FD_CLOEXEC; fcntl(fd, F_SETFD, fdflags);
a source to share