简体   繁体   English

Fork() 代码未按预期工作 - 层次结构制作

[英]Fork() code not working as expected - Hierarchy making

Good afternoon.下午好。

I am currently working on a C program that takes one and only one parameter which designates the number of "child generation"s to be created (the own father counts as 1 already).我目前正在开发一个 C 程序,该程序采用一个且只有一个参数来指定要创建的“子代”的数量(自己的父亲已经算作 1)。 "wait()" system calls are not to be used for this exercise (the version with "wait" calls happens to work exactly as expected). “wait()”系统调用不用于本练习(带有“wait”调用的版本恰好按预期工作)。

For instance, the call $program 4 should generate a hierarchy like this: Process A creates B Process B creates C Process C creates D例如,调用 $program 4 应该生成这样的层次结构: 进程 A 创建 B 进程 B 创建 C 进程 C 创建 D

The printed messages are not important, as they are merely orientative for the task.打印出来的信息并不重要,因为它们只是任务的导向。 With the following code (which happens to work exactly how I want with a "wait()" call) states that all the child processes derive from the same father, which I don't understand why it's happening.使用以下代码(恰好通过“wait()”调用完全按照我想要的方式工作)表明所有子进程都来自同一个父亲,我不明白为什么会这样。

#include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>

    int main(int argc, char *argv[]) {
    int counter; pid_t result; int i;

    /*
    We are going to create as many processes as indicated in argv[1] taking into account that the main father already counts as 1!
    */
    if (argc > 2 || argc == 1) {puts("IMPOSSIBLE EXECUTION\n"); exit(-1);}
    int lim = atoi(argv[1]);


    //We eliminate the impossible cases
    if (lim < 1) {puts("IMPOSSIBLE EXECUTION\n"); exit(-1);}


    if (lim == 1) {puts("The father himself constitutes a process all by his own, therefore:\n");
    printf("Process%d, I'm %d and my father: %d\n", counter, getpid(), getppid());
     }
    else {
        for (i = 0; i < lim; i++) {
            result = fork();
            if (result < 0) {
                printf("Call%d \n", counter); perror("Has failed!");
                exit(-1);
            }
            else if (result) {
                break; //Father process
            }
            else {
                counter++;    //Child processes increment the counter
                printf("Process%d, I am %d and my father: %d\n", counter, getpid(), getppid());
            }
        }
    }

The hierarchy generated by the code above is not the one I expected...上面代码生成的层次结构不是我所期望的......

All help is greatly appreciated.非常感谢所有帮助。 Thank you谢谢

With the following code (which happens to work exactly how I want with a "wait()" call) states that all the child processes derive from the same father, which I don't understand why it's happening.使用以下代码(恰好通过“wait()”调用完全按照我想要的方式工作)表明所有子进程都来自同一个父亲,我不明白为什么会这样。

I don't see that in my tests, nor do I have any reason to expect that it's actually the case for you.我在我的测试中没有看到这一点,我也没有任何理由期望它实际上是你的情况。 HOWEVER, it might appear to be the case for you if what you see is some or all of the child processes reporting process 1 as their parent.但是,如果您看到的是部分或全部子进程将进程 1 报告为其父进程,那么您可能会出现这种情况。 That would happen if their original parent terminates before the child's getppid() call is handled.如果他们的原始父母在孩子的getppid()调用被处理之前终止,就会发生这种情况。 Processes that are orphaned in that way inherit process 1 as their parent.以这种方式孤立的进程继承进程 1 作为它们的父进程。 If the parent wait() s for the child to terminate first then that cannot happen, but if instead the parent terminates very soon after forking the child then that result is entirely plausible.如果父母wait()让孩子首先终止,那么这不会发生,但如果父母在分叉孩子后很快终止,那么这个结果是完全合理的。

Here's a variation on your loop that will report the original parent process ID in every case:这是您的循环的一个变体,它将在每种情况下报告原始父进程 ID:

    pid_t my_pid = getpid();

    for (i = 0; i < lim; i++) {
        result = fork();
        if (result < 0) {
            printf("Call%d \n", counter); perror("Has failed!");
            exit(-1);
        } else if (result) {
            break; //Father process
        } else {
            pid_t ppid = my_pid;  // inherited from the parent
            my_pid = getpid();
            counter++;    //Child processes increment the counter
            printf("Process%d, I am %d and my father: %d\n", counter, (int) my_pid, (int) ppid);
        }
    }

You are missing a crucial function call.您错过了一个关键的 function 调用。

    for (i = 0; i < lim; i++) {
        fflush(stdout);             // <============== here
        result = fork();

Without it, your fork duplicates parent's stdout buffer into the child process.没有它,您的fork会将父级的标准输出缓冲区复制到子进程中。 This is why you are seeing parent process output repeated several times --- its children and grandchildren inherit the output buffer.这就是为什么您会看到父进程 output 重复多次 --- 它的子进程和孙子进程继承了 output 缓冲区。

Live demo (with fixed formatting for your reading convenience).现场演示(为您的阅读方便固定格式)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM