특정 프로세스 트리를 생성하고 종료합니다.

특정 프로세스 트리를 생성하고 종료합니다.

저는 현재 컴퓨터 시스템 강좌를 수강하고 있는데 숙제에 문제가 있습니다. 다음과 같은 특정 프로세스 트리를 만들어야 합니다.

프로세스 트리

또한 사용자가 pstree를 사용하여 터미널에서 검색하고 거기에 있는지 확인할 수 있도록 잠시 동안(sleep() 사용) 이 상태를 유지해야 합니다. 그런 다음 뒤로 종료해야 합니다(먼저 D, B, C 순으로). 지금까지는 트리를 생성할 수 있지만 트리의 나머지 부분이 생성되기 전에 항목 C가 종료되므로 A->B->D로만 끝납니다. 내 exit(1) 줄 때문에 이런 일이 발생한다는 것은 알지만, 이를 어디에 두어야 할지, 다른 방법이 있는지는 모르겠습니다.

지금까지 내 코드는 다음과 같습니다.

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

int main() {

int status = 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;
}

이것은 내가 현재 얻는 결과입니다.

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

이상적으로는 "부모는 자식 2828이 반환 값 1로 끝나는 것을 알고 있습니다." 줄은 항상 끝에 있어야 합니다. 미리 감사드립니다!

답변1

sleepC가 즉시 종료되지 않도록 하려면 사용해야 합니다 . 그러나 구조에서 A는 B와 D를 생성하기 전에 C가 종료될 때까지 기다립니다.

그래서:

  • waitC의 블록을 B의 블록과 같은 위치 에 놓습니다.wait
  • C가 종료되기 전에(또한 B 및 D가 종료되기 전에) 절전 모드 추가
  • B보다 두 배나 오래 기다리고 싶지 않기 때문에 B의 수면이 D의 대기보다 앞에 있는지 확인하세요.
  • 각 하위 프로세스에 대한 올바른 반환 값을 얻으려면 waitpid대신 를 사용해야 합니다 wait.

전체 코드는 다음과 같습니다.

#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;
}

해당 출력은 다음과 같습니다.

나는 : 24450

안녕하세요. 저는 프로세스 C(24451)이고, 상위 프로세스는 24450입니다.

안녕하세요. 저는 프로세스 B(24452)이고, 상위 프로세스는 24450입니다.

안녕하세요. 저는 프로세스 D(24453)이고, 상위 프로세스는 24452입니다.

부모는 자식 D(24453)가 완료되었고 값 3을 반환했음을 알고 있습니다.

부모는 자식 B(24452)가 완료되었고 값 2를 반환했음을 알고 있습니다.

부모는 자식 C(24451)가 완료되었으며 값 1을 반환했음을 알고 있습니다.

관련 정보