在c中创建顺序子 - 子进程

时间:2018-03-11 05:43:12

标签: c

我希望创建一个能够创建指定数量子节点的顺序进程。例如,如果父进程ID为769,则进程如下:

769(parent) -> 770(first child) -> 771(grand child) ... -> xx (n*grand child)

根据我想要的孩子数量。孩子的PID无关紧要,只要它们是连续的并且没有兄弟姐妹。

int main(int argc, char **argv) {
    int i;
    int iterations;

    if (argc != 2) {
        fprintf(stderr, "Usage: forkloop <iterations>\n");
        exit(1);
    }

    iterations = strtol(argv[1], NULL, 10);

    int n = fork();
    for (i = 0; i < iterations; i++) {
        if(n == 0) {
            printf("ppid = %d, pid = %d, i = %d\n", getppid(), getpid(), i);
            n = fork();
        }
        if (n < 0) {
            perror("fork");
            exit(1);
        }
       //printf("ppid = %d, pid = %d, i = %d\n", getppid(), getpid(), i);
    }
    // printf("ppid = %d, pid = %d\n", getppid(), getpid());
    return 0;
}

我已经做到了,但我相信这有点不对劲。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

仔细考虑逻辑。你很亲密,但需要靠近。这有效:

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

int main(int argc, char **argv)
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage: forkloop <iterations>\n");
        exit(1);
    }

    int iterations = strtol(argv[1], NULL, 10);
    if (iterations < 1 || iterations > 20)
    {
        fprintf(stderr, "invalid iterations %d (1..20 allowed)\n", iterations);
        exit(1);
    }
    printf("Initial process: PID %d (parent %d)\n", (int)getpid(), (int)getppid());
    fflush(stdout);
    int i;
    for (i = 0; i < iterations; i++)
    {
        int pid = fork();
        if (pid < 0)
        {
            perror("fork");
            exit(1);
        }
        else if (pid == 0)
        {
            /* Child - report ID */
            printf("ppid = %d, pid = %d, i = %d\n", getppid(), getpid(), i);
            fflush(stdout);
        }
        if (pid != 0)
        {
            /* Parent - break loop and wait for kid (and grandkid, and ...) to die */
            break;
        }
    }

    int corpse;
    int status;
    while ((corpse = wait(&status)) > 0)
    {
        printf("PID %d: child %d exited with status 0x%.4X\n",
               (int)getpid(), corpse, status);
        fflush(stdout);
    }

    return i;
}

(不保证pid_t等人返回的getpid()实际上是int,虽然它通常是等效的。我添加了强制转换以确保没有问题,但是练习你可以在没有它们的情况下离开。最后fflush()并不是严格需要的;进程退出时无论如何都会刷新输出。较早的是一个好主意;如果它们不存在你可能会得到令人困惑的输出和输出该程序通过管道传输到某个进程来捕获它。在你fork()之前,没有待处理的输出是个好主意 - 所以fflush(0)又名fflush(NULL)或许是一个好主意,一般来说,虽然这里没有必要。)

示例输出(源代码kids17.c,程序名称kids17):

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
>     -Wstrict-prototypes kids17.c -o kids17 
$ kids17
Usage: forkloop <iterations>
$ kids17 4
Initial process: PID 2686 (parent 888)
ppid = 2686, pid = 2687, i = 0
ppid = 2687, pid = 2688, i = 1
ppid = 2688, pid = 2689, i = 2
ppid = 2689, pid = 2690, i = 3
PID 2689: child 2690 exited with status 0x0400
PID 2688: child 2689 exited with status 0x0300
PID 2687: child 2688 exited with status 0x0200
PID 2686: child 2687 exited with status 0x0100
$ …some work done…
$ kids17 10
Initial process: PID 2704 (parent 888)
ppid = 2704, pid = 2705, i = 0
ppid = 2705, pid = 2706, i = 1
ppid = 2706, pid = 2707, i = 2
ppid = 2707, pid = 2708, i = 3
ppid = 2708, pid = 2709, i = 4
ppid = 2709, pid = 2710, i = 5
ppid = 2710, pid = 2711, i = 6
ppid = 2711, pid = 2712, i = 7
ppid = 2712, pid = 2713, i = 8
ppid = 2713, pid = 2714, i = 9
PID 2713: child 2714 exited with status 0x0A00
PID 2712: child 2713 exited with status 0x0900
PID 2711: child 2712 exited with status 0x0800
PID 2710: child 2711 exited with status 0x0700
PID 2709: child 2710 exited with status 0x0600
PID 2708: child 2709 exited with status 0x0500
PID 2707: child 2708 exited with status 0x0400
PID 2706: child 2707 exited with status 0x0300
PID 2705: child 2706 exited with status 0x0200
PID 2704: child 2705 exited with status 0x0100
$

在我运行此测试时,我没有任何其他进程主动生成子进程。