Ubuntu
創建特定的程序樹並終止它
我目前正在上電腦系統課程,但遇到了家庭作業問題。我必須創建這個特定的程序樹:
我還需要它保持這種狀態一段時間(使用 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 之前退出。所以 :
- 將
wait
C 的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 結束