Ubuntu

創建特定的程序樹並終止它

  • March 1, 2018

我目前正在上電腦系統課程,但遇到了家庭作業問題。我必須創建這個特定的程序樹:

程序樹

我還需要它保持這種狀態一段時間(使用 sleep()),以便使用者可以使用 pstree 在終端中查找它並查看它是否存在。然後它必須向後終止(首先是 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 結束”這一行應該一直放在最後。提前致謝!

你必須使用sleep來阻止 C 立即退出。但是在你的結構中,你有 A 等待 C 在它產生 B 和 D 之前退出。

所以 :

  • waitC 的wait塊與 B的塊放在同一位置
  • 在 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 結束

引用自:https://unix.stackexchange.com/questions/427535