How to share memory between processes created by fork()?

前端 未结 3 1823
傲寒
傲寒 2020-11-22 15:30

In fork child, if we modify a global variable, it will not get changed in the main program.

Is there a way to change a global variable in child fork?



        
相关标签:
3条回答
  • 2020-11-22 15:48

    Here is an alternative solution.

    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <sys/stat.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    typedef struct
    {
      int id;
      size_t size;
    } shm_t;
    
    shm_t *shm_new(size_t size)
    {
      shm_t *shm = calloc(1, sizeof *shm);
      shm->size = size;
    
      if ((shm->id = shmget(IPC_PRIVATE, size, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) < 0)
      {
        perror("shmget");
        free(shm);
        return NULL;
      }
    
      return shm;
    }
    
    void shm_write(shm_t *shm, void *data)
    {
      void *shm_data;
    
      if ((shm_data = shmat(shm->id, NULL, 0)) == (void *) -1)
      {
        perror("write");
        return;
      }
    
      memcpy(shm_data, data, shm->size);
      shmdt(shm_data);
    }
    
    void shm_read(void *data, shm_t *shm)
    {
      void *shm_data;
    
      if ((shm_data = shmat(shm->id, NULL, 0)) == (void *) -1)
      {
        perror("read");
        return;
      }
      memcpy(data, shm_data, shm->size);
      shmdt(shm_data);
    }
    
    void shm_del(shm_t *shm)
    {
      shmctl(shm->id, IPC_RMID, 0);
      free(shm);
    }
    
    int main()
    {
      int var = 1;
      shm_t *shm = shm_new(sizeof var);
    
      int pid;
      if ((pid = fork()) == 0)
      { /* child */
        var = 5;
        shm_write(shm, &var);
        printf("child: %d\n", var);
        return 0;
      }
      /* Wait for child to return */
      int status;
      while (wait(&status) != pid);
      /* */
      shm_read(&var, shm);
      /* Parent is updated by child */
      printf("parent: %d\n", var);
      shm_del(shm);
      return 0;
    }
    

    Build with:

    $ gcc shm.c -o shm && ./shm
    
    0 讨论(0)
  • 2020-11-22 15:55

    You can use shared memory (shm_open(), shm_unlink(), mmap(), etc.).

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/mman.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <unistd.h>
    
    static int *glob_var;
    
    int main(void)
    {
        glob_var = mmap(NULL, sizeof *glob_var, PROT_READ | PROT_WRITE, 
                        MAP_SHARED | MAP_ANONYMOUS, -1, 0);
    
        *glob_var = 1;
    
        if (fork() == 0) {
            *glob_var = 5;
            exit(EXIT_SUCCESS);
        } else {
            wait(NULL);
            printf("%d\n", *glob_var);
            munmap(glob_var, sizeof *glob_var);
        }
        return 0;
    }
    
    0 讨论(0)
  • 2020-11-22 16:07

    Changing a global variable is not possible because the new created process (child)is having it's own address space.

    So it's better to use shmget(),shmat() from POSIX api

    Or You can use pthread , since pthreadsare sharing the globaldata and the changes in global variable is reflected in parent.

    Then read some Pthreads tutorial.

    0 讨论(0)
提交回复
热议问题