变量的作用域(使用 fork() 和 wait()) [duplicate]

The scope of a variable(using fork() and wait()) [duplicate]

提问人:MasterWolfy 提问时间:9/6/2023 更新时间:9/6/2023 访问量:60

问:

我正在学习等待和分叉函数,我正在尝试打印出父进程和子进程的总和,但由于某种原因,总和似乎在父进程中被重新初始化为零,我也不确定我实现等待函数的方式,因为我在网上找到的所有资源都在 c 而不是 c++ 中。

#include <sys/wait.h>
#include <unistd.h>
#include <iostream>

int Sum = 0;

void printout()
{
  int id = fork();
  if(id!=0)
  {
    wait(NULL);
  }

  if(id == 0)
  {
    Sum += 2;
  }

  if(id!= 0)
  {
    Sum += 3;
  }
}

int main()
{
    printout();
    std::cout<<Sum<<std::endl;
}

我期待以下输出:

5

但我得到的 outpu 是:

2
3
C++ 分叉 等待

评论

3赞 Silvio Mayolo 9/6/2023
fork()不与子项共享全局变量。关键是新进程获取程序在那一刻的状态的副本。当时这两个变量都为零,因此您实际上没有在两者之间进行任何通信。fork()
0赞 Ripi2 9/6/2023
来自 fork 文档“子进程和父进程在单独的内存空间中运行”。所以,使用“fork”后不共享Sum
0赞 Nate Eldredge 9/6/2023
至于为什么你会得到两行输出,而不是你似乎期望的一行:父级和子级完全独立运行,所以它们都会在完成后返回,因此两者都将执行输出语句。调用的特定函数没有什么特别之处;系统调用在机器级别运行,与源代码的结构方式无关。(顺便说一句,当你的函数不打印任何东西时,命名它很奇怪。mainprintout()fork()printout()

答:

2赞 Joshua Ryandafres 9/6/2023 #1

您面临的问题是,系统调用创建了一个新的子进程,该子进程是父进程的精确副本,包括其变量和内存。但是,子进程和父进程具有单独的内存空间。这意味着,当您修改子进程中的变量时,它不会影响父进程中的变量,反之亦然。fork()SumSum

在代码中,父进程和子进程具有自己单独的变量副本,并且它们正在递增各自的副本。在函数中打印时,仅打印父进程中变量的值。SumSummainSum

如果要获取在父进程和子进程中修改的值的总和,可以使用进程间通信 (IPC) 机制,如管道或共享内存。

例如,使用管道:

#include <sys/wait.h>
#include <unistd.h>
#include <iostream>

int main() {
    int Sum = 0;
    int pipe_fd[2]; // Create a pipe for communication

    if (pipe(pipe_fd) == -1) {
        perror("pipe");
        return 1;
    }

    int id = fork();

    if (id == -1) {
        perror("fork");
        return 1;
    }

    if (id == 0) { // Child process
        close(pipe_fd[0]); // Close the read end of the pipe in the child process
        int childSum = 2;
        write(pipe_fd[1], &childSum, sizeof(childSum)); // Write childSum to the pipe
        close(pipe_fd[1]); // Close the write end of the pipe in the child process
    } else { // Parent process
        close(pipe_fd[1]); // Close the write end of the pipe in the parent process
        read(pipe_fd[0], &Sum, sizeof(Sum)); // Read the child's value from the pipe
        close(pipe_fd[0]); // Close the read end of the pipe in the parent process
        Sum += 3; // Modify the Sum in the parent process
        wait(NULL);
        std::cout << Sum << std::endl; // Output the final sum
    }

    return 0;
}