###### tags: `operating system` `note` `thu` # Chapter 2: Processes ## Interrupt的硬體結構 ![](https://i.imgur.com/TQgwgKc.png) ![](https://i.imgur.com/C8kc1XL.png) ## Process Control Block / PCB ![](https://i.imgur.com/wMf5Og1.jpg) ## ISR的實行步驟 (Interrupt Service Routine) ### 1. 先禁止更多的 INT(中斷) ### 2. 將CPU暫存器目前的內容取出(pop),並存入PCB。 ### 3. Check中斷的種類。 ### 4. Check中斷的來源。(e.g 哪個裝置) ### 5. 執行中斷(插入)的工作。 ### 6. 設定Timer ### 7. 清除中斷暫存器、事件暫存器(Input/Output/Timer)、中斷旗標。 ### 8. 排程(找下一個process、資料轉換) - Select a process from Ready Queue - Context switch (把PCB內的資料換入CPU的暫存器裡) ## 一個Process的一生 ![](https://i.imgur.com/TkcvL3N.jpg) ### 1. New 一個Process剛出生時的狀態。 ### 2. Ready 在這個狀態中,Process已被載入主記憶體,並等待作業系統的臨幸... Ready state中的processes被存在一個Ready queue當中。 ### 3. Running 當Process被選中執行後,就會進入這個狀態。 ### 4. Waiting / Block 在等待I/O或被其它比較長時間的工作擋住(程式邏輯/資源)時,Process就會進入這個狀態。 ### 5. Terminated Process就被消滅了,連同他家的PCB一起... ![](https://i.imgur.com/b1KzAbQ.png) ### 結論: **~~小孩要殺~~** --- ## 在System call的過程中,作業系統做的事情... ## 1. fork() : 産生小孩(Child process) ```c /** * Creates a new process by duplicating the calling process. * * @return int On success, the PID of the child process is returned in the parent's * thread of execution, and a value of 0 is returned in the child's thread * of execution. On failure, -1 is returned in the parent's context, no * child process is created, and an error code is stored in `errno`. */ pid_t fork(void); ``` ### 1. 先為小孩預約新的PCB。 ### 2. 為小孩預約記憶體空間。 - 預約的空間是空白的,沒有code section也沒有stack, heap。 ### 3. 為小孩要求新的PID ### 4. 將目前process的PCB複制至小孩的PCB上 - 依情形很可能需要修改, e.g. PID。 ### 5. 複製家長記憶體資料給小孩記憶體 - 複制的包含記憶體的內容跟其格式。 - 但是其中的內容可能會隨著小孩執行而改變。 ### 6. 把小孩ID給家長,返回0給小孩 - 執行fork的家長,會收到小孩未來的PID。 - 當家長收到小孩回傳的0時,就知道小孩已經正式成為他的小孩了。 ### 7. 把2個process放到Ready階段 - 都完成之後, 就可以把兩個process都放入ready queue - 等待系統的臨幸。 ## 2. exec() : 執行 process ```c /** * Replaces the current process image with a new process image. * * @param const char* path The path of the new process image to be loaded into the * current process. This can be a path to an executable file * or a script that can be executed by an interpreter. * * @param char* const argv[] An array of pointers to null-terminated strings that * represent the argument list available to the new process. * * @param char* const envp[] An array of pointers to null-terminated strings that * represent the environment variables available to the * new process. * * @return int On success, this function does not return to the caller. Instead, * the new process image is loaded into the current process, and execution * continues from its entry point. On failure, a value of -1 is returned, * and an error code is stored in `errno`. */ int exec(const char *path, char *const arglist[]); ``` **if** (指定的目標可執行程序在當前目錄或創建的路徑之一) * 將當前process移動到blocked state (沒被執行,PCB上的資源也被釋出) * 開始載入當前程式 **else** * 告知說:指定的目標可執行程序不存在 * 通知排程程式 ## 3. exit() : 關閉(kill) process ```c /** * Terminates the calling process. * * @param int status The exit status of the process, to be returned to the parent * process. The value 0 typically indicates success, while nonzero * values indicate failure or other conditions. * * @return void This function does not return to the caller. Instead, the process * is terminated, its resources are released, and the exit status is * returned to the parent process. */ void exit(int status); ``` 1. 關閉被目前process打開的檔案 2. 依作業系統不同(By ChatGPT, 但老師說都會殺掉小孩): - (Windows) 殺掉他的小孩(Recursive的呼叫exit()) - (Linux) 只殺掉他自已 3. 釋出記憶體空間 4. 釋出PCB及其上的資源。