저는 현재 컴퓨터 시스템 강좌를 수강하고 있는데 숙제에 문제가 있습니다. 다음과 같은 특정 프로세스 트리를 만들어야 합니다.
또한 사용자가 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
sleep
C가 즉시 종료되지 않도록 하려면 사용해야 합니다 . 그러나 구조에서 A는 B와 D를 생성하기 전에 C가 종료될 때까지 기다립니다.
그래서:
wait
C의 블록을 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을 반환했음을 알고 있습니다.