Criando uma árvore de processos específica e finalizando-a

1

Atualmente, estou cursando uma aula de Sistemas de Computação e estou tendo problemas com um problema de lição de casa. Eu tenho que criar esta árvore de processos específica:

Eutambémprecisoqueelefiquenesseestadoporumtempo(usandosleep())paraqueumusuáriopossaprocurá-lonoterminalusandoopstreeeverqueeleexiste.Entãodeveterminarparatrás(primeiroD,depoisB,depoisC).Atéagora,eupossofazeraárvore,masotermoCterminaantesqueorestodaárvoresejafeito,entãoeusóterminocomA->B->D.Euseiqueissoestáacontecendoporcausadaminhasaída(1)linha,maseunãoseimaisondecolocarissoouseexisteoutramaneira.

Códigoquetenhoatéagora:

#include<stdio.h>#include<sys/types.h>#include<unistd.h>#include<stdlib.h>#include<sys/wait.h>intmain(){intstatus=0;printf("I am: %d\n\n", (int)getpid());
pid_t pid = fork(); // fork a child

if(pid == 0)
{
    printf("Hi I'm process %d and my parent is %d\n",getpid(),getppid());
    exit(1);
}
else
{
    pid_t childPid = wait(&status);
    int childReturnValue = WEXITSTATUS(status);
    printf("parent knows child %d finished with return value %d\n\n", (int) childPid, childReturnValue);

    pid_t pid = fork(); // fork a child
    if (pid == 0)
    {
        printf("Hi I'm process %d and my parent is %d.\n", getpid(), getppid());
        pid = fork(); // fork a child
        if (pid == 0)
        {
            printf("Hi I'm process %d and my parent is %d.\n",getpid(),getppid());
            exit(3);
        }
        else
        {
            pid_t childPid = wait(&status);
            int childReturnValue = WEXITSTATUS(status);
            printf("parent knows child %d finished with return value %d\n\n", (int) childPid, childReturnValue);
        }
        exit(2);
    }
    else
    {
        pid_t childPid = wait(&status);
        int childReturnValue = WEXITSTATUS(status);
        printf("parent knows child %d finished with return value %d\n\n", (int) childPid, childReturnValue);
    }
}

return 0;
}

Aqui está a saída que estou recebendo atualmente:

I am: 2827

Hi I'm process 2828 and my parent is 2827
parent knows child 2828 finished with return value 1

Hi I'm process 2829 and my parent is 2827.
Hi I'm process 2830 and my parent is 2829.
parent knows child 2830 finished with return value 3

parent knows child 2829 finished with return value 2

Idealmente, a linha "pai sabe que o filho 2828 terminou com um valor de retorno 1" deve ser todo o caminho no final. Obrigado antecipadamente!

    
por Namit Patel 01.03.2018 / 19:56

1 resposta

0

Você precisa usar sleep para impedir que o C seja encerrado imediatamente. Mas na sua estrutura, você tem A aguardando a saída do C antes que ele aumente B e D.

Então:

  • coloque o bloco wait para C no mesmo local que o bloco wait para B
  • adicionar um sono antes da saída de C (e também antes da saída de B e D)
  • como você não quer esperar por B para o dobro do tempo, garantir o o sono de B é antes da espera de D
  • para obter o valor de retorno correto para cada subprocesso, você deve usar waitpid em vez de wait .

Aqui está o código completo:

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

#define SLEEP_TIME 5

int main() {

int status;
printf("I am: %d\n\n", (int)getpid());
pid_t c_pid = fork(); // fork a child

if(c_pid == 0)
{
    printf("Hi I'm process C (%d) and my parent is %d\n",getpid(),getppid());
    sleep(SLEEP_TIME);
    exit(1);
}
else
{
    pid_t b_pid = fork(); // fork a child
    if (b_pid == 0)
    {
        printf("Hi I'm process B (%d) and my parent is %d.\n", getpid(), getppid());
        pid_t d_pid = fork(); // fork a child
        if (d_pid == 0)
        {
            printf("Hi I'm process D (%d) and my parent is %d.\n",getpid(),getppid());
            sleep(SLEEP_TIME);
            exit(3);
        }
        else
        {
            // sleep before wait - actually no effect as the wait for D also waits for SLEEP_TIME
            sleep(SLEEP_TIME);
            // Wait for D to quit
            waitpid(d_pid, &status, 0);
            int DReturnValue = WEXITSTATUS(status);
            printf("parent knows child D (%d) finished with return value %d\n\n", (int) d_pid, DReturnValue);
        }
        exit(2);
    }
    else
    {
      sleep(SLEEP_TIME);

      // Wait for B to quit
      waitpid(b_pid, &status, 0);
      int BReturnValue = WEXITSTATUS(status);
      printf("parent knows child B (%d) finished with return value %d\n\n", (int) b_pid, BReturnValue);

      // Wait for C to quit
                                    waitpid(c_pid, &status, 0);
      int CReturnValue = WEXITSTATUS(status);
      printf("parent knows child C (%d) finished with return value %d\n\n", (int) c_pid, CReturnValue);
    }
}

return 0;
}

Aqui está a saída correspondente:

I am: 24450

Hi I'm process C (24451) and my parent is 24450

Hi I'm process B (24452) and my parent is 24450.

Hi I'm process D (24453) and my parent is 24452.

parent knows child D (24453) finished with return value 3

parent knows child B (24452) finished with return value 2

parent knows child C (24451) finished with return value 1

    
por 01.03.2018 / 21:24