I have server, that use multiple processes (fork()). There are large blocks of data, that can be created by one process and should be shared between other processes.
So, i use shm_open + mmap to create shared memory and map it to virtual memory.
struct SharedData {
const char *name;
int descriptor;
void *bytes;
size_t nbytes;
}
void shared_open(SharedData *data, const char *name, size_t nbytes) {
int d = shm_open(name, O_RDONLY, S_IRUSR | S_IWUSR);
if (d != -1) {
void *bytes = mmap(NULL, nbytes, PROT_READ, MAP_SHARED, d, 0 );
data->name = name;
data->descriptor = d;
data->bytes = bytes;
data->nbytes = nbytes;
} else {
data->descriptor = -1;
}
}
void shared_create(SharedData *data, const char *name, void *bytes, size_t nbytes) {
int d = shm_open(name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (d != -1) {
if (nbytes = write(d, bytes, nbytes)) {
shared_open(data, name, nbytes);
}
shm_unlink(name);
}
}
void shared_close(SharedData *data) {
if (data->descriptor != -1) {
munmap(data->bytes, data->nbytes);
shm_unlink(data->name);
}
}
Initial process create shared memory object with shared_create, other processes opens it with shared_open
Is this approach valid? Are there more effective or more simple methods?
Your design looks reasonable. To stay within the POSIX guidelines of the API to shared memory you should use ftruncate instead of write to extend the size, see
http://man7.org/linux/man-pages/man7/shm_overview.7.html
You can always do a memcpy to initialize the contents.
If you were using c++ you could use boost interprocess, if nothing else you can take a look at their interface.
http://www.boost.org/doc/libs/1_51_0/doc/html/interprocess/sharedmemorybetweenprocesses.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With