当调用 fork() 时,子进程执行了哪部分代码?

What portion of code is executed by child process when fork() is called?

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>

int main() {
   int pid;
   int pids[3];
   int status;
   int numprocesses = 0;
   int total_processes = 3;
   while (numprocesses < total_processes) {
      pid = fork();
      
      // Child process
      if (pid == 0) {
         printf("In child process: process id is %d\n", getpid());
         sleep(5);
         return 4;
      } else {
         pids[numprocesses] = pid;
         numprocesses++;
         printf("In parent process: created process number: %d\n", pid);
      }
   }
   printf("Checking\n");
   
   // Waiting for 3rd child process
   waitpid(pids[total_processes - 1], &status, 0);
   if (WIFEXITED(status) != 0) {
      printf("process %d exited normally\n", pids[total_processes - 1]);
      printf("exit status from child is %d\n", WEXITSTATUS(status));
   } else {
      printf("process %d not exited normally\n", pids[total_processes - 1]);
   }
   return 0;
}

我的期望是 'Checking' 应该从父进程和子进程打印字符串。但是 'Checking' 字符串只打印一次。

这是否意味着子进程只会执行 if (pid == 0) {..} 中的代码?

Does that mean only the code present in if (pid == 0) {..} will be executed by the child process?

是的。该块的末尾有一个 return 语句。 child 在那一点退出。

Does that mean only the code present in if (pid == 0) {..} will be executed by the child process?

是的,是的。成功时,父进程返回子进程的 PID,子进程返回 0。失败时,父进程返回-1,不创建子进程,并设置errno来指示错误。

您的代码检查 0(父进程)但不检查 -1(错误)。应该...

My expectation was 'Checking' string should have been printed from parent as well as child process. But 'Checking' string is printed only once.

您 post 的代码有此 child 特定代码:

      // Child process
      if (pid == 0) {
         printf("In child process: process id is %d\n", getpid());
         sleep(5);
         return 4;
      } else {
      ...

和最后的 return 4; 语句使 child 到 return main() 并且不执行之后的部分while循环。

确实,这可以使您免于某些事情...这就是,您的单身 parent 的所有 children 都可以 return 4; 而您的 parent 应该做尽可能多的 wait() 调用以等待所有 children。如果任何 child 已经脱离循环,因为他们没有 fork() 他们将从 wait 得到 return 并有一个错误(errno == ECHILD)表明没有 child 已经创建,正在等待。

所以,唯一脱离循环的进程是在循环中创建的所有 child 个进程中的 parent 个。所以应该只有一个 Checking,因为只有一个进程执行它。

如果你应该有 break; 循环而不是 return 4;,那么你应该有一个 Checking 每个 child,错误调用 wait,还有一个 parent,只有一个 child 被通知(哪个是不可预测的,很可能是第一个 exit(2)s)