背景
最近開始看 《Operating Systems: Three Easy Pieces》這本書,為了方便以后自己回顧和總結(jié),想以文章的方式,做成筆記?,F(xiàn)在的打算是看完書里的1 到 2 章內(nèi)容后,寫一篇文章,所以這將會(huì)是一系列的文章。前天剛好看完前三章,這將是第一篇筆記。
資源
因?yàn)槭堑谝黄恼拢詴?huì)將自己的學(xué)習(xí)資源列舉一下,這些學(xué)習(xí)的資源都是開源的:
- 書籍: 《Operating Systems: Three Easy Pieces》
- Project: https://github.com/remzi-arpacidusseau/ostep-projects
- xv6: 一個(gè)專門用于學(xué)習(xí)的操作系統(tǒng)
- 系統(tǒng): 類 unix 系統(tǒng)
Process
這本書說的 three pieces,指的是 Virtualization、Concurrency 和 Persistence。所以我們首先學(xué)習(xí)的是 Virtualization,這其中最重要的就是 process。之前不管是工作中或是學(xué)習(xí)中經(jīng)常會(huì)看到 process (也就是進(jìn)程),會(huì)覺得是個(gè)非常抽象的概念,根本不知道到底是什么個(gè)東西。趁此機(jī)會(huì),我們剛好可以仔細(xì)研究這個(gè)東西。
Definition
it is a running program
process 是一個(gè)程序,所以想要明白 process ,我們只需去搞清楚這個(gè)程序干了什么。
Why Virtualization
我們先來(lái)看下本書的第一部分 Virtualization 到底指什么,process 和這個(gè) Virtualization 有什么關(guān)系?
首先,我們都知道任何一個(gè)操作系統(tǒng)都可以同時(shí)運(yùn)行多個(gè) program,可以肯定的是 CPU 的數(shù)量是遠(yuǎn)遠(yuǎn)少于 program。那么操作系統(tǒng)是如何在這種條件下同時(shí)運(yùn)行多個(gè) program ,這個(gè)問題的答案就是 process 的功能之一 virtualizing the CPU 。
CPU Virtualization
操作系統(tǒng)可以在運(yùn)行一個(gè) process 的時(shí)候,停止運(yùn)行這個(gè) process,然后運(yùn)行其它 process,循環(huán)往復(fù)。對(duì)于 process 來(lái)說,不管物理 CPU 有幾個(gè),就好像它都有一個(gè)的專門的 virtualized CPU,來(lái)運(yùn)行 process。這種技術(shù)也被稱為 time sharing of the CPU。既然現(xiàn)在每個(gè) process 都有了自己的 CPU,那在 process 加載了所要運(yùn)行的 program 之后,對(duì)于 program 來(lái)說,就好像有一個(gè)專門的 CPU 在運(yùn)行自己。
Implementation
那如何實(shí)現(xiàn)這個(gè) CPU Virtualization,要從兩方面著手:
- low-level machinery mechanisms
- policies
第一點(diǎn)書里舉了個(gè)例子是 context switch,也就是我們?nèi)绾螐囊粋€(gè) process 的相關(guān)環(huán)境切換到另一個(gè) process 的相關(guān)環(huán)境,這個(gè)之后會(huì)重點(diǎn)講。第二點(diǎn)書里舉的例子是 scheduling policy,也就是說我們什么時(shí)候去切換 process,切到哪個(gè) process 等等的一些列決策問題。總結(jié)來(lái)說,我們要寫 process 轉(zhuǎn)換的代碼和做轉(zhuǎn)換的相關(guān)決策(??)。
Part Of Process
接著我們來(lái)看下 process 的組成部分,也就是所謂的 context
- memory (內(nèi)存)
One obvious component of machine state that comprises a process is its memory. Instructions lie in memory; the data that the running program reads and writes sits in memory as well. Thus the memory that the process can address (called its address space) is part of the process
- registers (寄存器)
- I/O information
Finally, programs often access persistent storage devices too. Such I/O information might include a list of the files the process currently has open.
Process API
之前我們說了 process 是一個(gè)程序,那一個(gè)程序必然會(huì)提供一些 API 來(lái)讓其它程序使用,我們可以先簡(jiǎn)單的看幾個(gè) process API。
Create: An operating system must include some method to create new processes. When you type a command into the shell, or double-click on an application icon, the OS is invoked to create a new process to run the program you have indicated.
Destroy: As there is an interface for process creation, systems also provide an interface to destroy processes forcefully. Of course, many processes will run and just exit by themselves when complete; when they don’t, however, the user may wish to kill them, and thus an interface to halt a runaway process is quite useful.
Wait: Sometimes it is useful to wait for a process to stop running; thus some kind of waiting interface is often provided.
Miscellaneous Control: Other than killing or waiting for a process, there are sometimes other controls that are possible. For example, most operating systems provide some kind of method to suspend a process (stop it from running for a while) and then resume it (continue it running).
Status: There are usually interfaces to get some status information about a process as well, such as how long it has run for, or what state it is in.
這些 API 看名字應(yīng)該也能知道大致的作用,這里我們簡(jiǎn)單地瀏覽下,后面的章節(jié)會(huì)去使用并解釋這些接口。
Process Creation: A Little More Detail
我們?cè)賮?lái)看下 process 加載其它 program 的步驟:
- load its code and any static data from disk into the address space of the process lazily
- Some memory must be allocated for the program’s run-time stack (or just stack)
- The OS will also likely initialize the stack with arguments; specifically, it will fill in the parameters to the main() function, i.e., argc and the argv array
- the OS may also allocate some memory for the program’s heap
- The OS will also do some other initialization tasks, particularly as related to input/output (I/O)
- to start the program running at the entry point, namely main()
Process States
process 在運(yùn)行的時(shí)候,有可能會(huì)處于不同的狀態(tài),我們先來(lái)看簡(jiǎn)化的狀態(tài):
- Running
In the running state, a process is running on a processor. This means it is executing instructions
- Ready
In the ready state, a process is ready to run but for some reason the OS has chosen not to run it at this given moment
- Blocked
In the blocked state, a process has performed some kind of operation that makes it not ready to run until some other event takes place
上傳一個(gè)書中的狀態(tài)轉(zhuǎn)移圖:

Data Structures
具體的 process 的數(shù)據(jù)結(jié)構(gòu)
struct context {
uint edi;
uint esi;
uint ebx;
uint ebp;
uint eip;
};
enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
// Per-process state
struct proc {
uint sz; // Size of process memory (bytes)
pde_t* pgdir; // Page table
char *kstack; // Bottom of kernel stack for this process
enum procstate state; // Process state
int pid; // Process ID
struct proc *parent; // Parent process
struct trapframe *tf; // Trap frame for current syscall
struct context *context; // swtch() here to run process
void *chan; // If non-zero, sleeping on chan
int killed; // If non-zero, have been killed
struct file *ofile[NOFILE]; // Open files
struct inode *cwd; // Current directory
char name[16]; // Process name (debugging)
};
這段代碼來(lái)自 xv6 ,可以自己下載源碼去看看
結(jié)尾
這本書簡(jiǎn)化很多了東西,讀起來(lái)也是通俗易懂,可以作為我們操作系統(tǒng)的入門書。但是也不是說一點(diǎn)要求沒有,很明顯需要知道 C 語(yǔ)言。其次,因?yàn)樯婕暗綏?,匯編等等,需要配合 CSAPP 一起看。CSAPP 這本書剛好我也在看,下幾篇的文章我在記錄操作系統(tǒng)知識(shí)點(diǎn)的時(shí)候,剛好也可以把在 CSAPP 學(xué)到的相關(guān)知識(shí)點(diǎn)也記錄進(jìn)來(lái),知識(shí)的連接才是最重要的。