C
fork 系統呼叫是如何工作的
我有一個關於 fork 系統呼叫的非常具體的問題。我有這段程式碼:
int main (void) { for (int i = 0; i < 10; i++) { pid_t pid = fork (); if ( !pid ) { printf("CHILD | PID: %d, PPID: %d\n", getpid(), getppid()); _exit(i + 1); } } for (int i = 0; i < 10; i++) { int status; waitpid(-1, &status, 0); if (WIFEXITED(status)) { printf("IM %d AND CHILD WITH EXIT CODE %d TERMINATED\n", getpid(), WEXITSTATUS(status)); } else { printf("ERROR: CHILD NOT EXITED\n"); } } return 0; }
產生這個輸出:
CHILD | PID: 3565, PPID: 3564 CHILD | PID: 3566, PPID: 3564 IM 3564 AND CHILD WITH EXIT CODE 1 TERMINATED IM 3564 AND CHILD WITH EXIT CODE 2 TERMINATED CHILD | PID: 3573, PPID: 3564 CHILD | PID: 3567, PPID: 3564 IM 3564 AND CHILD WITH EXIT CODE 9 TERMINATED IM 3564 AND CHILD WITH EXIT CODE 3 TERMINATED CHILD | PID: 3568, PPID: 3564 IM 3564 AND CHILD WITH EXIT CODE 4 TERMINATED CHILD | PID: 3569, PPID: 3564 IM 3564 AND CHILD WITH EXIT CODE 5 TERMINATED CHILD | PID: 3570, PPID: 3564 IM 3564 AND CHILD WITH EXIT CODE 6 TERMINATED CHILD | PID: 3571, PPID: 3564 IM 3564 AND CHILD WITH EXIT CODE 7 TERMINATED CHILD | PID: 3572, PPID: 3564 IM 3564 AND CHILD WITH EXIT CODE 8 TERMINATED CHILD | PID: 3574, PPID: 3564 IM 3564 AND CHILD WITH EXIT CODE 10 TERMINATED
這讓我想知道 fork 到底是如何工作的,以及新程序真正執行了哪些程式碼。看上面的輸出結果,看不懂:
- 在第一個完成所有迭代之前,第二個循環如何列印?我還注意到第二個 for總是由父程序執行,這讓我想知道 while on first for cycle(這意味著父程序呼叫)第二個 for cycle是否被執行(?)
if pid != 0
- 為什麼 CHILD 程序不按 PID 排序列印?
那麼,最重要的是,fork 究竟是如何工作的,誰執行了什麼?
當你
fork
時,核心創建一個新程序,它是分叉程序的副本,兩個程序在之後繼續執行fork
(返回程式碼顯示是否發生錯誤,以及正在執行的程式碼是父程序還是子程序)。這個“繼續執行”的部分不一定會立即發生:核心只是將新程序添加到執行隊列中,它最終會被調度並執行,但不一定立即執行。這解釋了您所詢問的兩種行為:
- 由於不一定會立即安排新程序,因此父程序可能會在任何子程序有機會執行之前繼續執行;
- 創建順序在執行隊列中沒有太大(如果有的話)影響,因此不能保證子程序將按照它們創建的順序執行。