【问题标题】:using reference value of pointer when using fork() in linux在linux中使用fork()时使用指针的引用值
【发布时间】:2013-08-01 01:55:51
【问题描述】:

我正在尝试在使用 fork() 时更新我尝试写入的整个应用程序中的整数指针的值。我无法理解,我想在分叉期间发生了什么。它与主要变量不共享相同的变量吗?当它们在分叉中发生变化时,我怎样才能让 main 更新它的值。这是我创建的一个示例,用于了解我想要做什么:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

void changeValue(int *value)
{
  *value = *value * 2;
  printf("value in changeValue(): %d\n", *value);
}

main ()
{
  int pid;
  int *value = new int;
  *value = 10;
  printf("value in main: %d\n", *value);

  pid = fork();
  if (pid == 0) {
    changeValue(value);
    _exit(0);
  }

  sleep(2);
   // I want value = 20 here, but value stays = 10
  printf("value in main after fork(): %d\n", *value);
} 

【问题讨论】:

    标签: c++ pointers reference fork


    【解决方案1】:

    如果您希望从子级更新父级中的值,则必须将其放入shared memory,因为这是一种进程间通信。我建议使用mmap 创建共享内存。这是一个例子:

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/mman.h>
    
    void changeValue(int *value)
    {
      *value = *value * 2;
      printf("value in changeValue(): %d\n", *value);
    }
    
    int main()
    {
      int pid;
      int *value = (int*)mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
      *value = 10;
      printf("value in main: %d\n", *value);
    
      pid = fork();
      if (pid == 0) {
        changeValue(value);
        _exit(0);
      }
    
      sleep(2);
       // I want value = 20 here, but value stays = 10
      printf("value in main after fork(): %d\n", *value);
    } 
    

    还有一个示例运行:

    $ ./a.out
    value in main: 10
    value in changeValue(): 20
    value in main after fork(): 20
    

    【讨论】:

    • 漂亮!!谢谢!!救了我!!
    • 只是我在手册页上读到的内容:MAP_ANON 似乎已被弃用;请改用 MAP_ANONYMOUS(请参阅mmap
    【解决方案2】:

    您将不得不使用进程间通信 (IPC) 在父进程和子进程之间进行通信。您可以使用消息队列、管道或共享内存来做到这一点。如果您使用共享内存,请确保使用信号量或其他东西来确保修改共享内存时互斥。

    当您调用 fork() 时,它会创建一个相同的进程,但子进程会获得自己的内存空间和堆,因此不会共享变量。这就是为什么必须使用 IPC 进行进程间通信的原因。

    您可以在此处了解有关使用共享内存的更多信息:http://www.cs.cf.ac.uk/Dave/C/node27.html 您可以在此处了解有关消息队列的更多信息:http://www.cs.cf.ac.uk/Dave/C/node25.html 消息队列比管道更好用,但如果您想了解有关管道的更多信息,可以在这里:https://www.cs.rutgers.edu/~pxk/416/notes/c-tutorials/pipe.html

    【讨论】:

      【解决方案3】:

      它不共享与 main 相同的变量吗?

      没有。它在调用fork().时创建进程地址空间的副本

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-26
        • 1970-01-01
        • 1970-01-01
        • 2014-01-07
        • 2021-12-16
        • 2014-05-06
        • 1970-01-01
        相关资源
        最近更新 更多