---
# System prepended metadata

title: 'Chapter 2: Processes'
tags: [operating system, note, thu]

---

###### 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及其上的資源。
