---
# System prepended metadata

title: 系統程式筆試考古題2018
tags: [考古題]

---

# 系統程式筆試考古題2018
###### tags: `考古題`

1. 請簡單比較一下傳統Linux的權限控制及ACL（使用getfacl和setfacl）的權限控制，舉一個例子說明傳統Linux的權限控制做不到，而ACL做得到
>ACL：access control list
setfacl提供更細部的權限控制，而某些情況傳統Linux的權限控制是不足的。
因為傳統Linux指提供三種權限：usr, grp, others。如果今天要開放四種不同的權限（使用者、校友、老師、在校生），就一定得使用ACL。
```c=
//授予myuser使用者rx權限
setfacl -m u:myuser:rx myfile.txt
```
參考影片：
https://www.youtube.com/watch?v=fPBzoDszDh8

2. 請問如何用google查詢到監測檔案系統的函數名稱（hint：要下哪些關鍵字）
>"linux c inotify function"

```c=
//持續監看tmp目錄下的所有檔案事件
inotifywait -m /tmp
//對檔案做一些操作
date > /tmp/date.output
rm /tmp/date.output
```



這時候就會看到 inotifywait 的輸出中出現以下的檔案事件訊息：
/tmp/ CREATE date.output
/tmp/ OPEN date.output
/tmp/ MODIFY date.output
/tmp/ CLOSE_WRITE,CLOSE date.output
/tmp/ DELETE date.output

參考影片：
https://www.youtube.com/watch?v=F0Jk8AAWwv8&ab_channel=ShiwuLo


3. 目前在Linux系統中只有「一個」行程（該行程為prog）是活躍的狀態（active，換句話說就是需要CPU），其他行程都是inactive的狀態（目前不需要CPU）。請問下列這些指令會讓這個行程的執行時間造成什麼樣的影響（hint: nice -n -5是提高此行程對其他行程的優先權，nice -n 5是降低此行程對其他行程的優先權）
sudo nice -n -5 prog
sudo nice -n 5 prog
>毫無影響。nice是用於需要CPU的process之間互相搶奪，才有作用。
因為只有一個active process，所以沒有影響。

4. 請問下列程式的執行結果，解釋你的答案
```c=
printf(“Hello ”);
fork();
printf(“Ron\n”);
```
>將會印出：
helloRon <= parent
helloRon <== child
因為printf預設是line buffered，所以hello會被存在buffer，fork完之後，child和parent在buffer都有hello，所以會印出來兩次。

5. 請描述如何同時對parent和child除錯
Hint<attach ,set waiting = 0 ,while loop>
>gdb預設是對parent除錯，可使用set follow-fork-mode child切換為對child除錯。
>![](https://i.imgur.com/JhFKaSU.png)
https://ephrain.net/gdb-%E4%BD%BF%E7%94%A8-gdb-%E9%99%A4%E9%8C%AF-fork-%E5%87%BA%E4%BE%86%E7%9A%84%E5%AD%90%E9%80%B2%E7%A8%8B/
https://visualgdb.com/gdbreference/commands/set_follow-fork-mode

6. 請問何謂殭屍行程
>child已經結束，而**parent沒有回收child在process table裡的entry**，造成資源的浪費。

7. System()和execv()都可以執行外部程式，請問下列程式碼會在螢幕上印出多少個"fork"?

```c=
int main(int argc, char* argv[]){
    system("ls");
    fork();
    fork(); 
    printf("fork\n");
    return 0;
}
```
>fork兩次，會印出四次”fork”。


```c=
int main(int argc,char* argv[]){
    char* const para_list[] = {"/bin/ls","-l",NULL};
    execv("/bin/ls",para_list);
    fork();
    fork();
    printf("fork\n");
    return 0;
}
```
>0次，因為exec家族的函數會把整個process換掉，之後的函式都沒有效用。
>實際上，system()是靠著fork、wait和exec(“sh”, “ -c”,  cmd)實做出來的。

8. 請問可以使用signal函數攔截ctr-c這組按鍵輸入嗎？
> 可以，使用signal(SIGINT, sig_handler);

9. Linux中signal編號1-31，與編號SIGRTMIN~SIGRTMAX這兩個族群有什麼不同？
Hint<如果連續、大量的發送signal各會發生什麼事情>
>前面32個是不可靠訊號，後面的是可靠訊號。
不可靠訊號指的是發送的次數和接受次數常常不同，比如：在sighandler之中，sleep()，然後連續按十次ctrl+c。可能只會收到第一次ctrl+c。
可靠的訊號雖然稱為可靠，只要送訊號的速度快到OS kernel無法負荷，也不是那麼可靠。


10. 程式碼如下：在上一回合的執行當中，程式執行到C函數。在這一回合的執行中，程式碼執行到B函數的時候可以使用longjmp到C函數嗎？（提示：想一下堆疊的狀態）
```c=
    sigjmp_buf jmp_buf_a, jmp_buf_b;
    A() { setjump(&jmp_buf_a); B(); }
    B() { 
       if(XXX) longjmp(&jmp_buf, 1);
       C(); 
    }
    C() { setjmp(&jmp_buf_c);}
```
>可以，上一回合執行C()，**已經設定好SP、PC、R0~R31**，在B()之中，可以透過longjmp指令跳回C()。

11. 請解釋dup這個函數的用途，請說明下列程式碼中printf(“hello\n”)會將資料寫到哪個地方（pipe？螢幕？）
```c=
pipe(pipefd);
ret = fork();
if (ret==0) {	/*child*/
    close(1);
    dup(pipefd[1]);
    close(pipefd[1]);
    close(pipefd[0]);
    printf("hello\n");
} else { /*...*/}
```
>將一個無人使用的file descriptor，指向dup參數中的fd所指向的file table。以上方程式為例，將1號fd關閉，然後將1號指向pipefd[1]所指向的file table。
printf會寫到pipe之中，因為stdout已經被重新指向了。
12. 請問pipe可否「繼承」給子行程，如果沒有特殊的設定，請問執行execve-like的系統呼叫以後，pipe可否繼承給新載入的程式碼（提示：在Linux內可以打像下列這樣的指令：$ ls -R / | sort，bash如何達成這樣的指令呢？）
>子行程可以繼承pipe。在exec之前將stdout導向到pipe，可以在exec之後存取pipe。
比如：$ ls -R / | sort，
第一個process(ls)會將stdout指向pipefd[1]，然後執行exec(“ls”);
接著第二個process(sort)會把stdin導向到pipfd[0]，才執行exec(“sort”)。

13. mutex在大部分的情況都比semaphore快，請提出一個例子，說明非使用semaphore不可。
>semaphore只要一去等待，就會context switch，而context switch是有overhead(大約10,000個cycle)，要是critical section的程式很短，用semaphore就很不划算。
>但是在多個thread想進入critical section，要sem_wait的時候，**寧願context switch也不要一直跑while loop**，佔用CPU資源。
>**參考影片**：
>https://www.youtube.com/watch?v=-OLyMcH2jqc
14. 請說明adaptive mutex在鎖定時的機制。（提示：假設p嘗試進入critical section，而q已經在critical section內了。這時候如果1.） p, q在同一個core會怎樣，如果2.) q正在waiting會怎樣，如果3.) q不在waiting會怎樣，分別針對前述三個狀況，回答sleep或spinlock（即，busy waiting））
>sleep指的就是ctx-switch
>1. p, q在同一個core：p進入sleep狀態
>2. q正在waiting：p進入sleep狀態（因為q沒有進度，p不可能等到）
>3. q不在waiting ：p會busy waiting（因為q正在跑，p猜他快等到了）
https://www.youtube.com/watch?v=-OLyMcH2jqc&t=1293s
15. 宣告全域變數前，如果加上 “_ _thread” 這個關鍵字，那麼編譯器會怎樣處理各個thread對該全域變數的存取？（提示：32位元會使用gs暫存器，64位元會用fs暫存器，然後對變數...）
>變數會變成thread local storage，也就是每一個thread都擁有一份自己的變數。
16. 請問下列二種id在使用上的差別
```c=
ptid = pthread_create(...);
tid = gettid() 
int gettid() { return syscall(SYS_gettid);}
```
>那兩種id?看不懂題目
>gettid ＝ get thread id
>因為libc沒有實做這個system call，所以只能自定義一個函式。
17. 下列何者最能描述授課老師對於同學們的最高期許
>乾坤大挪移
18. 中正作業系統實驗室，及所開設的課程屬於哪一個門派？
>明教


