---
# System prepended metadata

title: 'linux2021: n795113'

---

# linux2021: n795113
:::warning
注意細節！
:notes: jserv
:::

## 測驗 γ-1
解釋程式碼輸出 - 字元數量的原理
```cpp
int main(void)
{
    for (int i = 0; i < NNN; i++) {
        fork();
        printf("-");              
    }

    fflush(stdout);
    return 0;
}
```

### Fork
首先，必須先理解 [fork()](https://www.geeksforgeeks.org/fork-system-call/) 在幹嘛。</br>
看完我們大致可以理解到，當遇到 fork()，執行就會分岔成父、子 2 個行程 (process)。</br>

那如果連續多個 fork() 會是如何呢？
```cpp
#include <stdio.h>
#include <sys/types.h>
int main()
{
    fork();
    fork();
    fork();
    printf("-\n");
    return 0;
}
```
結果：
```
-
-
-                                                                                                                                                                               
-
-
-
-
-
```

如果是更接近題目的形式呢？可以思考一下</br>

遇到 fork 後先分支成 2 個進程，並複製之後的程式碼；</br>
從被複製的的程式碼角度來看，前面有 n 個 fork，就會被複製 2^n 次。</br>

所以 i=0 的 printf 被複製到 1 次，有 2 個。</br>
所以 i=1 的 printf 被複製到 2 次，有 4 個。</br>
所以 i=2 的 printf 被複製到 2 次，有 8 個。</br>

加總起來應該會有 14 行會輸出。
``` C
#include <stdio.h>
#include <sys/types.h>
int main()
{
    fork();
    printf("i=0 -\n");
    fork();
    printf("i=1 -\n");
    fork();
    printf("i=2 -\n");
    return 0;
}
```
結果：
```
i=0 -
i=0 -
i=1 -
i=1 -
i=2 -
i=1 -
i=1 -
i=2 -
i=2 -                                                                                                                                                                                                                   
i=2 -
i=2 -
i=2 -
i=2 -
i=2 -
```

### 結果不如預期？

### buffer？

* printf 不會馬上把內容印出來，會存在緩存，而 fork 在複製時也會複製緩存
* 如果在 printf 後加上 fflush，輸出字元數就會是 2^NNN 了
``` C
int main(void)
{
    for (int i = 0; i < NNN; i++) {
        fork();
        printf("-");   
        fflush(stdout);// 清空暫存            
    }

    fflush(stdout);
    return 0;
}
```

---

## 測驗 ϵ-1
解釋 memory pool 程式碼運作原理

### Free-list
* 一個未使用 pools 的清單，head 指向這清單的開頭
* 要分配記憶體的時候基本上是回傳 head 指向的位置

### 分配記憶體 Allocation
* 分配記憶體會回傳可用記憶體的起始地址
* 分配前會先看 memory pool 裡空間夠不夠，不夠的情況有兩種，會需要增加 pool 並更新 free-list head：

 1. 所需的記憶體 > 整個 block
 2. 剩餘記憶體 < 所需的記憶體 < 整個 block
 
* 最後 free-list 所指向的位置，並再更新 free-list head，指向被取用區塊的下一個區塊

### 釋放記憶體 Deallocation
欲被釋放的 pool 的下一個 pool 指向現在 free-list 的 head 所指向的 pool。</br>
而 free-list 的 head 再改指向欲被釋放的 pool
