在 C 中创建多个进程(Parent 有几个 children)

Creating Multiple Processes in C (Parent with several children)

我在学校学习 C 和 Linux。我的任务是创建一个 parent 进程,它创建 3 个 child 进程。创建的 child 进程不应再有 children。我必须证明所有进程同时存在。此后 Parent 应等待创建的 child 进程终止。

这是我的代码:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main() {
    int i;
    int var = 0;
    printf("I am the Parent, my ID: %d\n", getpid());
    for( i = 0; i < 3; i++ ) {
        if(var == 0) {
            if( fork() == 0 ) {
                var++;
                printf("Child: PID: %d; PPID: %d\n", getpid(), getppid() );
                printf("Var:%d \n", var);
            }
        }
    }
    sleep(3);
    int status;
    wait(&status);
    printf("%d says bye!\n", getpid());
}

我的输出:

I am the Parent, my ID: 273
Child: PID: 274; PPID: 273
Var:1 
Child: PID: 275; PPID: 273
Var:1 
Child: PID: 276; PPID: 273
Var:1 

我也试过用 WEXITSTATUS() 打印出来,但这只是 parent 过程,他用 0.

表示

此代码创建了一个 parent 进程及其 3 个 child 进程,没有进一步的 children 作为例外。但是我如何让 parent 等待 3 children 终止以及我如何 show/proof 所有进程可以同时存在?

让我们从您当前代码的问题开始:

  1. 您没有通过在需要时显式终止 children 来分离 parent/child 代码。您代码中的每个 child 将继续执行 for 循环,然后执行 wait() 之后的代码,它应该只由 parent.[=28= 执行]

  2. 你不是在等所有的children。如果创建 3 children,则需要进行 3 wait() 次调用,每个 child 次调用。在您的情况下,顺序并不重要,因此您可以使用 wait() 而不是 waitpid()/wait3()/wait4(),但您需要另一个循环。

  3. 您没有检查您使用的任何函数的错误。你绝对应该!

  4. 我有点想念你的 var 变量的要点,如果只是为了避免在 child 代码中进入循环体,那么一个简单的breakexit()return 就足够了。

您的代码的正确版本如下:

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

int main() {
    unsigned i;
    int status;
    pid_t child_pid;

    printf("I am the Parent, my PID: %d\n", getpid());

    for (i = 0; i < 3; i++) {
        child_pid = fork();

        if (child_pid == -1) {
            perror("fork() failed");
            return 1;
        } else if (child_pid == 0) {
            printf("Child: PID: %d; PPID: %d\n", getpid(), getppid() );
            sleep(3);
            printf("Child %d says bye!\n", getpid());
            return 0;
        }
    }

    for (i = 0; i < 3; i++) {
        child_pid = wait(&status);
        if (child_pid == -1) {
            perror("wait() failed");
            return 1;
        }

        if (WIFEXITED(status)) {
            printf("Child %d exited with code %d\n", child_pid, WEXITSTATUS(status));
        } else {
            // Handle other cases here like WIFSIGNALED, WIFSTOPPED, etc...
            // See `man 2 wait` for more information.
        }
    }

    return 0;
}

how do I show/proof that all processes can exist at same time?

这可以通过很多不同的方式来完成。您可以在生成 3 个 child 之后使用 ps 之类的程序在另一个终端上从外部执行此操作(可能将睡眠增加到 10 秒以获得更多时间):

$ ps --ppid 249626 # get this from the output of your program
    PID TTY          TIME CMD
 249627 pts/1    00:00:00 test
 249628 pts/1    00:00:00 test
 249629 pts/1    00:00:00 test

或者您可以通过在 children 代码中打印程序开始和执行结束的时间来做到这一点:

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

void print_time(void) {
    time_t t;
    struct tm *local;
    const char *local_str;

    t = time(NULL);
    if (t == (time_t)-1) {
        perror("time() failed");
        return;
    }

    local = localtime(&t)
    if (local == NULL) {
        perror("localtime() failed");
        return;
    }

    local_str = asctime(&local);
    if (local_str == NULL) {
        perror("asctime() failed");
        return;
    }

    ptintf("Child %d time: %s\n", getpid(), local_str);
}

// ... same code as before ...

        } else if (child_pid == 0) {
            printf("Child %d PPID: %d\n", getpid(), getppid() );
            print_time();
            sleep(3);
            printf("Child %d says bye!\n", getpid());
            print_time();
            return 0;
        }

// ... same code as before ...

输出:

I am the Parent, my PID: 250469
Child 250470 PPID: 250469
Child 250471 PPID: 250469
Child 250470 time: Tue Oct 26 23:53:03 2021
Child 250472 PPID: 250469
Child 250471 time: Tue Oct 26 23:53:03 2021
Child 250472 time: Tue Oct 26 23:53:03 2021
Child 250470 says bye!
Child 250470 time: Tue Oct 26 23:53:06 2021
Child 250471 says bye!
Child 250471 time: Tue Oct 26 23:53:06 2021
Child 250472 says bye!
Child 250472 time: Tue Oct 26 23:53:06 2021
Child 250470 exited with code 0
Child 250471 exited with code 0
Child 250472 exited with code 0