Domanda

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?

È stato utile?

Soluzione

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top