---
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
> 
> 補充:`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題 題目

> **讓我們加上一些註解,方便判斷。**
> ```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
> 
為了方便觀察,這邊以循序的方式畫各個 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)
## 備註
覺得有問題的話歡迎來信指點!