Как заставить родительский процесс ждать, пока дочерние процессы не завершатся sh? - PullRequest
1 голос
/ 27 апреля 2020

У меня есть назначение, которое дает мне этот код для преобразования в код, который заставляет родительский процесс ожидать завершения всех дочерних процессов sh. 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");
            }
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 28 апреля 2020

Это не сработает, но я надеюсь, что этого совета достаточно, чтобы вы пошли. Задание кажется загадкой вокруг fork(), у вашего учителя хороший вкус: -)

fork() отличается. Возвращается дважды.

  • В родительском элементе возвращается идентификатор процесса созданного процесса.
  • В дочернем элементе возвращается 0; процесс всегда может определить свой PID, используя getpid()

На самом деле назначение не является хорошим вкусом. Обычно код, использующий `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;
}
0 голосов
/ 28 апреля 2020

Это один из способов сделать это; будет множество других.

#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("ERRO! 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
...