# 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