--- title: 111台聯大A4 計算機概論 第24題 `fork()` tags: Operating System --- <p xmlns:cc="http://creativecommons.org/ns#" >This work by <a rel="cc:attributionURL dct:creator" property="cc:attributionName" href="https://linktr.ee/k.wayne">K.Wei</a> is licensed under <a href="http://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">CC BY-SA 4.0<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1"><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1"><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg?ref=chooser-v1"></a></p> # 111台聯大A4 計算機概論 第24題 `fork()` ## 建議先備知識 - Overview 或 Foundation 的 OS 章節。 - 知道 Program、Process 的差別。 - [Process Manager](https://www.notion.so/cc01ef91930241ee9ee69b3ac3c8e9bb#fc17948e60734f1b8175cef3579299a6) - 知道 Process State 與 State Diagram - [State Diagram](https://www.notion.so/cc01ef91930241ee9ee69b3ac3c8e9bb#3972ad6b1ac0459ca7fd9011b9af6337) - Process $\rightarrow$ 行程 - PID $\rightarrow$ Process ID ## `fork()` 簡單說明 Process(已經在執行的 Code)只要碰到 `fork()`,就會直接從現在的位置直接岔一個新的 Process 出來。 意思就是,從 `fork()` 的下一行開始,會有兩個 Process 在執行,一個是原本的 Process,一個是新的 Process。 再換個角度想,現在起,多了一個新的 Process,只執行 `fork()` 之後的 Code。 ## `fork()` 簡單舉例 這是一個只有一個 `fork()` 的 C++ Code。 可想而知應該會產生一個 Child Process。 ```c++= #include <iostream> #include <unistd.h> using namespace std; int main(){ pid_t pid; cout << "before fork()" << endl; pid = fork(); cout << "after fork()" << endl; return 0; // end of this program } ``` > Terminal Output > ```cli > before fork() > after fork() > after fork() > ``` > Process Graph > ![Imgur](https://i.imgur.com/XQ0bN90.jpg) > 補充:`fork()` 回傳的 PID 有三個結果: > - `-1`:子行程建立失敗。 > - `0`:當前行程是子行程。 > - 整數:子行程的 PID。 在當今多核 CPU,父行程與子行程誰先執行誰後執行是不一定的,甚至有可能是同時執行。 記得一個關鍵,哪個 Process 執行了這個 `fork()`,哪個 Process 就是 Parent Process。例:Process A 執行到 `fork()`,岔出了 B Process,A 就是 Parent、B 就是 A 的 Child。 從上面的圖來看,main 執行了 `fork()`,main 是這個 `fork()` 的 Parent Process。而岔出來的 sub-process 就是 Child Process。 --- **總結一下上面說的內容:** - `pid = fork()` - 執行 `fork()`的人,稱為 Parent Process(父行程), `pid` 會是子行程的 PID,`pid > 0`。 - 岔出來新的 Process,稱為 Child Process(子行程),`pid = 0`。 - `fork()` 失敗,未創建子行程,`pid = -1`。 ## 第24題 題目 ![Imgur](https://i.imgur.com/BFUeEzT.png) > **讓我們加上一些註解,方便判斷。** > ```c++= > #include <stdio.h> > #include <unistd.h> > > int main(){ > for(int i=1; i<5; i++){ > if(fork() == 0) // f0 > fork(); // f1 > else{ > fork(); // f2 > fork(); // f3 > } > } > return 0; // end program > } > ``` > 補充: `if(fork()==0)` 中,呼叫了 `fork()`。因此不要忘記 `if` 內也會做一次 `fork()`。 > [color=red] > Process Graph > ![Imgur](https://i.imgur.com/0JdcZQn.jpg) 為了方便觀察,這邊以循序的方式畫各個 Process fork。 由圖可知,`i=1` 時,共 fork $5$ 次,產生 $5$ 個子行程。 因此我們知道,`i=1` 時,會讓 $1$ 個 Process 變成 $6$ 個。 接下來所有行程在 `i=2` 時,都能畫出一模一樣的 Precess Graph。 把 p1~p5 也當成新的 main。因此在 `i=2` 時, $6$ 個 Process 會變成 $6*6=36$ 個 Process(包含 main)。 同理 `i=3` 時, $36$ 個 Process 都一變六。 因此 `i=3` 結束時,共有 $36*6=216$ 個 Process。 那 `i=4` 就不用多說了, $216*6=1296$。 從上可知,最後共有 $1296$ 個 Process。答案選 `D`。 ## 參考資源 - [[Linux C] fork 觀念由淺入深](https://wenyuangg.github.io/posts/linux/fork-use.html) - NYCU Course - Introduction to Operating Systems - [Homework 1](https://drive.google.com/drive/folders/1UgPDnFqjlKiVWlg9RbWHc5e-bW3OXg-4?usp=sharing) ## 備註 覺得有問題的話歡迎來信指點! [LINKTREE](https://linktr.ee/k.wayne)