【问题标题】:child processes are not terminating correctly in c子进程在 c 中未正确终止
【发布时间】:2021-05-17 06:29:05
【问题描述】:

在学习分叉和进程方面还是新手,我有这个任务来创建 3 个子进程执行一些操作,然后父进程应该在它们终止时打印退出状态。

我遇到的问题是孩子 1 提前终止,我认为我没有正确使用 wait()。

这是我的代码:

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

int main( int argc, char *argv[] ) {
    pid_t child1,child2, child3,wpid;
    int child1Status,child2Status,child3Status;

child1 = fork();
   if (child1 == 0){
    float marks[8];
    float average = 0.0;
    float sum = 0.0;
    printf("I am child one my pid is %d \n",getpid());
    printf("Please enter 8 marks and I will calcuate the average and highest mark\n");
    for (int i = 0; i < 8; ++i) {
        printf("%i) ",i+1);
    scanf("%f", &marks[i]);
    sum += marks[i];
}
average = sum / 8;
printf("Average = %.2f and highest = %.2f\n", average,highest(&marks));
exit(1);
}
 else{
        
        child2 = fork();
         if (child2 == 0){
    

char *cmd = "wc";
        char *args[4];
    args[0] = "wc";
    args[1] = "-c";
    args[2] = "test.txt";
    args[3] = NULL;
         execvp(cmd, args);
      
         }
         else
        {
           child3 = fork();
            if (child3 == 0){
        

          char *cmd = "wc";
            char *args[4];
            args[0] = "wc";
            args[1] = -c;
            args[2] = "anotherfile.txt";
            args[3] = NULL;
            execvp(cmd, args);
             }
          else
            {

                
                wait(&child1Status);
                printf(" child one has exited with exit status %d \n", (child1Status >> 8));
                wait(&child2Status);
                printf(" child two has exited with exit status %d \n", (child2Status >> 8));
                wait(&child3Status);
                printf(" child three has exited with exit status %d \n", (child3Status  >> 8));
            }

}

在我当前的输出中,孩子 1 说它在我输入任何标记之前已经退出,而它应该说它在打印出最高和平均标记后已经退出。

我也知道,因为我在 child2 和 3 中使用了 execvp,所以 exit() 代码不会运行,在这种情况下我如何获得退出状态?

我还需要在所有子进程终止后打印“父进程已完成”,如何确保在我打印“父进程已完成”之前所有子进程都已终止

编辑:由于 cmets,将最后一个 else 块替换为以下内容

else
            {
                
                waitpid( child1,  &child1Status, 0);
                printf(" child one has exited with exit status %d \n", (child1Status >> 8));
                 waitpid( child2,  &child2Status, 0);
                printf(" child two has exited with exit status %d \n", (child2Status & 0x7F));
                 waitpid( child3,  &child3Status, 0);
                printf(" child three has exited with exit status %d \n", (child3Status & 0x80));
            }

以上所有3个子进程在最后一个接一个地退出,这不应该是这种情况

预期输出:

I am child 1 please enter 8 marks and i will find the average
I am child 2 here is the word count 
50
child 2 has exited 
i am child 3 here is the word count 
96 
child 3 has exited 
**enter 8 marks by user**
average is 
child 1 has exited
parent has finished

当前输出:

 I am child 1 please enter 8 marks and i will find the average
    I am child 2 here is the word count 
    50
  i am child 3 here is the word count 
    96 
**enter 8 marks by user**
    average is 
    child 1 has exited
child 2 has exited
child 3 has exited

【问题讨论】:

  • 编辑问题以提供minimal reproducible example。您似乎省略了检查问题所必需的代码。
  • 如果你想等待第一个孩子退出再创建第二个孩子,你应该把wait(&amp;child1Status);移到第二个叉子之前。
  • @mkayaalp 我不想在创建其他进程之前等待第一个孩子退出。在孩子 1 的代码完成运行之前,孩子 1 正在退出
  • 三个wait 调用不一定对应于您所指出的孩子一、二、三。谁先完成。您可以使用waitpid 等待特定的孩子。
  • @william_ 好的,我想您不想等待他们按此顺序完成。也许像以前一样使用wait,但使用返回值来确定哪个孩子完成了。

标签: c fork child-process


【解决方案1】:

由于各种错误,您的代码甚至无法编译...

不管怎样,看起来你想在孩子们一出现就显示它的结尾。为此,您应该循环 wait 直到没有更多的孩子等待,并使用返回值来知道哪个已经结束:

      ...
      else
        {

        for(;;) {    
            pid_t pid = wait(&child1Status);
            int child_num;
            if (pid == child1) child_num = 1;
            else if (pid == child2) child_num = 2;
            else if (pid == child3) child_num = 3;
            else break;   // no more child to wait...

            printf(" child %d has exited with exit status %d \n",
                   child_num, (child1Status >> 8));
        }
        }
        ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多