Question

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?

Était-ce utile?

La solution

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top