【问题标题】:How to wait for all child processes to terminate in C?如何等待所有子进程在 C 中终止?
【发布时间】:2023-02-21 19:25:47
【问题描述】:

我正在努力完成这项任务,而且我对它还很陌生。此任务要求我根据 C 中命令行参数中完整路径 unix 命令的数量创建直接子进程。

例如 ./main.c /bin/uname (创建 1 个叉子)

./main.c /bin/uname /bin/ls (创建 2 个叉子) ETC

每个子进程执行后,父进程将显示“命令 %s 已成功完成”或“命令 %s 未成功完成”。

所以这就是我的问题所在:

  1. 是不是for循环的缘故,每条命令执行完都会打印出语句“all good,bye bye!\n”?如果是这样,为什么等待呼叫不起作用?

  2. 睡眠呼叫有效吗?因为当运行第一个 unix 命令时,下一个命令会在第一个命令之后立即打印出来。

    3)我如何等待**所有**子进程终止并打印出“全部完成,再见!”

    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/wait.h>
    #include <unistd.h>
    #include <sys/types.h>
    
    void CreateChildren(int argCounter, char *argVector[]);
    
    int main(int argc, char *argv[])
    {
        CreateChildren(argc,argv);
        
        return 0;
    }
    
    void CreateChildren(int argCounter, char *argVector[])
    {
        int counter = 1;
        pid_t pid;
        
    
        printf("Program name is: %s\n\n", argVector[0]);
    
        if(argCounter == 1)
        {
            printf("No extra command line\n");
        }
    
        if(argCounter >= 2)
        {
            
            for(counter;counter < argCounter; counter++)
            {
                //create child process each time the counter increases
                pid = fork();
                
                if(pid < 0)
                {
                    printf("Unable to create child process\n");
                    exit(1);
                }else
                    if(pid == 0)
                    {
                        //child process. execute the command
                        execl(argVector[counter], argVector[counter], (char *)0);
                        sleep(100);
                        exit(0);
                    }else
                    {
                        //parent process
                        //wait will pass a pointer to an int. Returns a the process ID of the child process
                        //if the child pid is equals to the status of the wait then child process id is ok else it will return -1
    
                        int status;
                        if(pid == wait(&status))
                        {
                            printf("Command %s has completed successfully\n\n",argVector[counter]);
                        }else
                            printf("Command %s has NOT completed successfully\n\n", argVector[counter]);
    
                           
                        wait(&status);
                        printf("all good, bye-bye!\n");           
                    }    
            }
        }
    
        
    }
    

    执行程序的命令行参数

    ./main.c /bin/hostname /bin/date /bin/ls /bin/ps /bin/uname

    实际产量

    程序名称是:./main.c

    iconikeu-虚拟机

    命令 /bin/hostname 已成功完成

    一切都好,再见!

    2023 年 2 月 21 日星期二 05:48:37 下午 +08

    命令 /bin/date 已成功完成

    一切都好,再见!

    assignment1 assignment1.c cmds.txt main.c

    命令 /bin/ls 已成功完成

    一切都好,再见!

    PID TTY          TIME CMD
    

    77518 分/3 00:00:01 狂欢 102786 点/3 08:05:12 sh 115809 点/3 00:00:00 main.c 115813 点/3 00:00:00 秒

    命令 /bin/ps 已成功完成

    一切都好,再见!

    Linux

    命令 /bin/uname 已成功完成

    一切都好,再见!

    预期产出

    程序名称是:./main.c

    iconikeu-虚拟机

    命令 /bin/hostname 已成功完成

    2023 年 2 月 21 日星期二 05:48:37 下午 +08

    命令 /bin/date 已成功完成

    assignment1 assignment1.c cmds.txt main.c

    命令 /bin/ls 已成功完成

    PID TTY          TIME CMD
    

    77518 分/3 00:00:01 狂欢 102786 点/3 08:05:12 sh 115809 点/3 00:00:00 main.c 115813 点/3 00:00:00 秒

    命令 /bin/ps 已成功完成

    Linux

    命令 /bin/uname 已成功完成

    一切都好,再见!

【问题讨论】:

  • 跟踪所有启动的子进程及其 PID,然后检查 wait 返回的内容?
  • /main.c /bin/uname /bin/ls 你把 C 文件作为命令运行?通常您不运行 C 文件,而是编译它们,生成的可执行文件没有 .c 后缀。
  • @Gerhardh 很高兴你告诉我这件事。我不知道可执行文件没有 .c 后缀。谢谢
  • @Someprogrammerdude 好吧,我试试看
  • 这没什么大不了的,但是如果您将可执行文件命名为 .c,您可能会意外覆盖源文件。我们还在这里看到了作者试图在不编译的情况下执行 C 文件的问题。 (我没有在这个问题中假设。)

标签: c ubuntu-20.04


【解决方案1】:

printf("all good, bye-bye! "); 指令是里面循环,应该在什么时候外部.和

                    ...
                    if(pid == wait(&status))
                    {
                        printf("Command %s has completed successfully

",argVector[counter]);
                    }else
                        printf("Command %s has NOT completed successfully

", argVector[counter]);


                }
        }
        printf("all good, bye-bye!
");
    }
}

我正确地得到:

Program name is: ./main

my_hostname
Command /bin/hostname has completed successfully

Tue Feb 21 11:30:14 CET 2023
Command /bin/date has completed successfully

main main.c
Command /bin/ls has completed successfully

  PID TTY          TIME CMD
    9 pts/0    00:00:00 bash
  119 pts/0    00:00:00 main
  123 pts/0    00:00:00 ps
Command /bin/ps has completed successfully

Linux
Command /bin/uname has completed successfully

all good, bye-bye!

但请注意,由于您没有跟踪循环内可能出现的故障,因此即使某些命令未成功,此代码也将以 all good 结尾...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    • 2012-11-08
    • 2020-09-09
    相关资源
    最近更新 更多