Mmap and structure
I'm working some code including communication between processes, using semaphores. I made structure like this:
typedef struct container {
sem_t resource, mutex;
int counter;
} container;
and use in that way (in main app and the same in subordinate processes)
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));
Everythi开发者_开发技巧ng is fine when I use one of the sem_ functions, but when I try to do something like
memory->counter = 5;
It doesn't work. Probably I got something wrong with pointers, but I tried almost everything and nothing seems to work. Maybe there's a better way to share variables, structures etc between processes ? Unfortunately I'm not allowed to use boost or something similiar, the code is for educational purposes and I'm intentend to keep as simple as it's possible.
Because you're using shm_unlink()
immediately before shm_open()
, your two processes never open the same shared memory object - each one is creating a new, distinct object (even though they have the same name).
It's not clear what you mean by "doesn't work". The following minimal example, based on your code, works fine for me. What does it 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;
}
On reviewing your code, it's failing because you are trying to access the file descriptor in a child process after exec()
, and shm_open
sets the FD_CLOEXEC
flag by default so the file descriptor is no longer open in the child. So you just need to unset that flag in the main process (eg. right after checking for the error after shm_open
):
fdflags = fcntl(fd, F_GETFD);
fdflags &= ~FD_CLOEXEC;
fcntl(fd, F_SETFD, fdflags);
Why are you calling shm_open at all? A pretty good way to do this is to just call 'open' on some pathname and use that.
精彩评论