简体   繁体   中英

How to create shared memory after fork or in child process?

How to create shared memory after fork or in child process?

I want to first make a global pointer in shared memory, then in child process create multiple node dynamically and add the node to this global pointer.

#include <string.h>
#include <unistd.h>

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>

struct shm_t {
        int data;
        struct shm_t *next;
};

void main() {
        struct shm_t *shm = (struct shm_t *)mmap(NULL, sizeof(*shm), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0);

        shm->data = 1;
        shm->next = NULL;

        int pid = fork();

        if (pid == 0) {
                printf("Child \n");
                // How to create a shared shm_t here, and assign to *shm->next?
        } else {
                printf("Parent \n");
        }
}

In order for two processes to share memory, they have to have something in common.

Your first allocation is shared because you allocated it with MAP_SHARED , and the child process inherited it from the parent. Once the fork already finished, there is no way for that to happen automatically (just one example: which process does the child share this with? The parent is just a random process with no special significance, as far Linux is concerned).

The way to do this properly is be sharing a file descriptor. The number of pitfalls here, however, is staggering.

Let's start with the solution first, and then understand why it won't work:

// Before the fork
int shared_fd = open("/dev/shm/somefile", O_CREAT|O_TRUNC|O_EXCL|O_RDWR, 0600);
// Check for errors
unlink("/dev/shm/somefile");
// check for errors

// Now you can fork

If you now use mmap from this file, it is possible to share it between the processes (ie - one process' writes will be visible to the other process).

Like I said, the number of pitfalls here is huge:

  • The file is created empty, and you cannot mmap past the end of a file. In order for this to work, you will need to increase the file using ftruncate . Here is a problem, though. The calls to ftruncate will need to be synchronized, or you will have the lost update problem, where both processes think they are increasing the file to the same size together.
  • Even after you do that, you still cannot store pointers inside the memory. The reason is that the memory is shared, in the sense that one process' writes are immediately visible to the other. There is no guarantee, however, that they will be mapped to the same addresses.

I'm not sure what you want to do here (if you want to share a linked list between two processes, you have huge synchronization issues to handle here as well). If you can provide a-priori limit on how much memory you're going to need, just pre-allocate it with the original mmap .

In all likelihood, however, what you're trying to achieve here isn't possible in the way you're trying to achieve it (not in any sane way).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM