【问题标题】:How to make parent process wait for child processes to finish?如何让父进程等待子进程完成?
【发布时间】:2020-04-27 19:10:33
【问题描述】:

我有一个任务,它让我将此代码转换为使父进程等待所有子进程完成的代码。 PS:第一个代码有4个进程,需要使用waitpid来解决。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
  pid_t p = fork();
  pid_t k = fork();

  if(p>0){
     printf("p=%d: PID = %d\n", p, getpid());
     sleep(45);
     exit(0);
  }
  else if(p==0){
     printf("p=%d: PID = %d\n", p, getpid());
     exit(0);
  }
  else if(p<0){
     printf("ERRO! p=%d\n", p);
     exit(p);
  }
}

我已经尝试过了,但我认为这仅适用于 1 个子进程,而不适用于其中很多。

int main(){

    pid_t p = fork(); 
    pid_t k = fork(); 

    if(p<0){
        printf("fodeu");
        exit(p);
    }
    else if(p==0){
        printf("");
        exit(0);
    }
    else{
        for(i=0;i<4;i++){
            int returnstatus; 
            waitpid(p,&returnstatus,0);

            if(returnstatus == 0){
                printf("o processo filho correu normalmente");
            }
            else if(returnstatus == 1){
                printf("o processo filho ardeu");
            }
        }
    }
}

【问题讨论】:

  • 其实这只是你的问题之一。另一个是你忽略了k
  • 你从不使用k,第二个fork()的返回值。您需要p &gt; 0k &gt; 0 来识别原始进程,该进程必须完成大部分等待(它有两个孩子)。您原来的子进程也必须等待。最简单的方法是让每个进程等待它没有子进程——一个调用wait()waitpid() 并报告退出状态的while 循环。没有子进程的进程将立即退出循环并终止,允许其父进程继续。请注意,您的原始进程没有 4 个子进程; for 循环不合适。
  • 不要忘记在语句末尾打印一个换行符。如果您正在处理多个进程,最好将进程报告的 PID 包含在来自printf() 的输出中。

标签: c ubuntu fork pid waitpid


【解决方案1】:

这不会完成你的任务,但我希望这是足够的建议 你去。作业似乎是围绕fork() 的谜语,您的 老师很有品味:-)

fork() 不同。它返回两次。

  • 在父进程中,它返回创建进程的进程 ID。
  • 在子节点中返回 0;一个进程总是可以使用getpid() 来确定它的PID

其实这个作业没啥好品味的。通常使用 `fork() 编写代码 永远不要让任何分支逃逸到封闭代码中以避免完成 废话。像这样,

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

int main()
{
    pid_t pid = fork();
    if (pid == 0 /*child*/) {
        printf("PID %d (child) doing work\n", pid);
        sleep(5);
        exit(0); // don't let it continue (leak) into parent code
    }
    else if (pid > 0 /*parent*/) {
        int status;
        pid_t terminated;

        printf("PID %d (parent) waiting for child PID %d\n", getpid(), pid);

        terminated = waitpid(pid, &status, 0);
        if (terminated == -1) {
            perror("waitpid");
            exit(1);
        }

        if (WIFEXITED(status))
            printf("child exited normally with status %d\n", WEXITSTATUS(status));
        else
            printf("hm. child died otherwise. see 'man waidpid' for more\n");
    }

    return 0;
}

考虑到这一点,看看这两条看似无辜的线条,

pid_t p = fork(); // two processes after this
pid_t k = fork(); // executed by **two** processes, again duplicating

所以,在这两行之后,我们有四个进程执行其余的 代码并行。这是大脑爆炸的地方。什么 k 行的泄漏子在询问 p 的值时会做什么 是吗?

看看这个小程序的输出,看看效果如何 泄漏。

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

int main(){
  printf("MAIN PID %d\n", getpid());

  fork();
  fork();

  printf("PID %d, PPID %d\n", getpid(), getppid());
  return 0;
}

【讨论】:

    【解决方案2】:

    这是一种方法;还有很多其他的。

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/wait.h>
    #include <unistd.h>
    
    static void wait_for_kids(void);
    
    int main(void)
    {
        pid_t p = fork();
        pid_t k = fork();
    
        if (p > 0)
        {
            printf("p=%d: PID = %d\n", p, getpid());
            sleep(5);
            wait_for_kids();
            printf("%d: p = %5d, k = %5d - exiting\n", getpid(), p, k);
            exit(0);
        }
        else if (p == 0)
        {
            printf("p=%d: PID = %d\n", p, getpid());
            wait_for_kids();
            printf("%d: p = %5d, k = %5d - exiting\n", getpid(), p, k);
            exit(0);
        }
        else
        {
            printf("ERROR! p=%d\n", p);
            wait_for_kids();
            printf("%d: p = %5d, k = %5d - exiting\n", getpid(), p, k);
            exit(p);
        }
        /*NOTREACHED*/
    }
    
    static void wait_for_kids(void)
    {
        int corpse;
        int status;
        int pid = getpid();
    
        while ((corpse = waitpid(0, &status, 0)) > 0)
            printf("%d: child %d exited with status 0x%.4X\n", pid, corpse, status);
    }
    

    示例输出:

    p=43445: PID = 43444
    p=43445: PID = 43446
    p=0: PID = 43445
    p=0: PID = 43447
    43447: p =     0, k =     0 - exiting
    43445: child 43447 exited with status 0x0000
    43445: p =     0, k = 43447 - exiting
    43446: p = 43445, k =     0 - exiting
    43444: child 43445 exited with status 0x0000
    43444: child 43446 exited with status 0x0000
    43444: p = 43445, k = 43446 - exiting
    

    【讨论】:

      猜你喜欢
      • 2013-10-28
      • 1970-01-01
      • 1970-01-01
      • 2013-12-17
      • 1970-01-01
      • 1970-01-01
      • 2016-06-13
      • 2013-09-24
      • 1970-01-01
      相关资源
      最近更新 更多