为什么子进程的行为如此奇怪?

Why child process behaviour is so strange?

我写了一段创建子进程的代码。

代码片段:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <math.h>
void B();
void C();
void D();
void E();
int main (){
    int status;
    printf("Name: %s, PID: %d, PPID: %d.\n", "A", getpid(), getppid());
    if (fork() == 0) {
        B();
    }
    if (fork() == 0) {
        C();
    }
    wait(&status);  
}
void B(){
    //B process
    int status;
    printf("Name: %s, PID: %d, PPID: %d.\n", "B", getpid(), getppid());
    if (fork() == 0) {
        E();
    }
    if (fork() == 0) {
        D();
    }
    wait(&status);
}
void C(){
    //C process
    printf("Name: %s, PID: %d, PPID: %d.\n", "C", getpid(), getppid());
}
void E(){
    //E process
    printf("Name: %s, PID: %d, PPID: %d.\n", "E", getpid(), getppid());
}
void D(){
    //D process
    printf("Name: %s, PID: %d, PPID: %d.\n", "D", getpid(), getppid());
}

问题是我得到了完全出乎我意料的输出。 日志:

Name: C, PID: 4571, PPID: 4570.
Name: D, PID: 4572, PPID: 4569.
Name: C, PID: 4573, PPID: 4572.
Name: C, PID: 4574, PPID: 4567.
Name: C, PID: 4575, PPID: 4569.
------------------------------
Name: A, PID: 4576, PPID: 4147.
Name: B, PID: 4577, PPID: 4576.
Name: C, PID: 4578, PPID: 4576.
Name: D, PID: 4580, PPID: 4577.
Name: E, PID: 4579, PPID: 4577.
------------------------------
Name: D, PID: 4582, PPID: 4579.
Name: C, PID: 4581, PPID: 4580.
Name: C, PID: 4583, PPID: 4582.
Name: C, PID: 4584, PPID: 4577.
Name: C, PID: 4585, PPID: 4579.

每次发射都由------------------------

为什么C进程运行多次,每次都改变他的PPID? 为什么我看不到来自 A 进程(父进程)的消息? 等待您的回答和 link 资源!

您看到了缓冲 stdout 这一事实的副作用。我将您的程序修改为:

  1. 每次调用 printf 后刷新 stdout
  2. 添加了根据缩进级别打印缩进的功能。主进程的缩进级别是0。主进程子进程级别缩进为1,以此类推

我得到以下输出:

Name: A, PID: 694812, PPID: 23788.
   Name: B, PID: 695816, PPID: 694812.
   Name: C, PID: 693016, PPID: 694812.
      Name: E, PID: 691184, PPID: 695816.
      Name: D, PID: 695896, PPID: 695816.
         Name: D, PID: 691792, PPID: 691184.
            Name: C, PID: 696268, PPID: 691792.
         Name: C, PID: 695220, PPID: 695896.
      Name: C, PID: 694204, PPID: 695816.
         Name: C, PID: 695496, PPID: 691184.

修改后的程序如下:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <math.h>
void B();
void C();
void D();
void E();

void printIndent();

int indentLevel = 0;

int main (){
    int status;
    printIndent();
    printf("Name: %s, PID: %d, PPID: %d.\n", "A", getpid(), getppid());
    fflush(stdout);
    if (fork() == 0) {
       ++indentLevel;
       B();
    }

    if (fork() == 0) {
       ++indentLevel;
        C();
    }
    wait(&status);  
}

void B(){
    //B process
    int status;
    printIndent();
    printf("Name: %s, PID: %d, PPID: %d.\n", "B", getpid(), getppid());
    fflush(stdout);
    if (fork() == 0) {
       ++indentLevel;
        E();
    }
    if (fork() == 0) {
       ++indentLevel;
        D();
    }
    wait(&status);
}

void C(){
    //C process
    printIndent();
    printf("Name: %s, PID: %d, PPID: %d.\n", "C", getpid(), getppid());
    fflush(stdout);
}

void E(){
    //E process
    printIndent();
    printf("Name: %s, PID: %d, PPID: %d.\n", "E", getpid(), getppid());
    fflush(stdout);
}

void D(){
    //D process
    printIndent();
    printf("Name: %s, PID: %d, PPID: %d.\n", "D", getpid(), getppid());
    fflush(stdout);
}

void printIndent()
{
   int i = 0;
   for ( ; i < indentLevel; ++i )
   {
      printf("   ");
   }
}