進程
進程基本概念
進程包括程序代碼(又稱文本段或代碼段),當前活動(通過Program Counter和當前寄存器內的內容表示),進程堆棧段(包括臨時數據,比如函數參數、返回地址和局部變數)和數據段(包括全局變數),堆(用於運行時動態分配內存)。
程序:靜態的內容,可執行文件。
進程:活動的實體,有PC表示下一個要執行的命令和相關資源集合。
進程的狀態
PCB
進程狀態:上面說的new, ready, running, waiting, terminate
PC:表示進程要執行的下個指令的地址
CPU寄存器:包括累加器,索引寄存器,堆棧指針、通用寄存器和其它條件碼信息寄存器,用於保存一些中間狀態,以便之後能順利執行(比如執行了中斷之後)
CPU調度信息:進程優先順序,調度隊列指針和其它參數等
內存管理信息:基址寄存器和界限寄存器,頁表或段表
記賬(Accounting)信息:包括CPU時間、實際使用時間、時間界限、記賬數據、作業或進程數量等
I/O狀態信息:包括分配給進程的I/O設備列表,打開的文件列表等
進程間切換
進程調度基本概念
進程進入系統的時候會被加入作業隊列中,作業隊列保存了系統中的所有進程。
已經被調入內存中等待執行的的進程會進入Ready queue。
隊列用鏈表表示,有頭尾指針,以及指向當前正在運行的進程的current指針。
等待I/O的設備會被放進設備隊列。
Scheduler分為Long-term Scheduler和Short-term Scheduler。
對於批處理系統來說,long-term scheduler負責將提交了的作業從緩衝池中取出放進內存中(即放進Ready queue中),short-term scheduler(又叫做CPU scheduler)負責將進程從Ready queue中取出。
short-term scheduler因為需要頻繁執行調度,所以必須調度的速度要儘可能快。long-term scheduler需要選擇合適組合I/O-bound進程(大部分時間在做設備I/O)和CPU-bound進程(大部分時間在做計算)。不是所有的操作系統都有long-term scheduler。
time-sharing系統可能需要引入medium-term scheduler。medium-term scheduler的思想是能將進程從內存(and from active contention for the CPU)中移出,and thus reduce the degree of multi-programming。之後進程還能再被調入內存中繼續執行。這叫swapping。
通常,通過state save保存CPU當前狀態(不管是在kernel mode還是在user mode),之後通過state store重新執行。
上下文切換(context switch)的定義:Switching the CPU to another process requires performing a state save of the current process and a state restore of a different process. This task is known as a context switch.
上下文切換髮生時,內核將就舊進程的狀態保存在PCB中,然後裝入要執行的進程的上下文。
上下文切換屬於額外的時間開銷,速度因機器不同而不同。
進程創建
When a process creates a new process, two possibilities for execution exist:
1. The parent continues to execute concurrently with its children.
2. The parent waits until some or all of its children have terminated.
There are also two address-space possibilities for the new process:
1. The child process is a duplicate of the parent process (it has the same program and data as the parent).
2. The child process has a new program loaded into it.
UNIX系統中每個進程都用一個唯一的整數標識。父進程和子進程間可以通信。兩者都繼續執行fork()之後的指令。對於子進程來說,fork()的返回值為0;對於父進程來說,返回值為子進程的進程標識符pid。
通常系統在調用fork()之後還會繼續執行exec()來執行子進程,這樣子進程會取代父進程的內存空間。父進程能繼續創造更多的子進程,也可以通過wait()把自己從ready queue中移出,等待子進程終止。
進程終止
當進程完成執行最後的語句並使用系統調用exit()請求系統刪除自身的時候,進程終止。這個時候進程可以通過返回狀態值到父進程處(如果父進程執行了wait())。所有使用的資源(包括物理內存和虛擬內存,打開的文件,I/O緩衝)都會被系統釋放。
A parent may terminate the execution of one of its children for a variety of
reasons, such as these:
? The child has exceeded its usage of some of the resources that it has been allocated. (To determine whether this has occurred, the parent must have a mechanism to inspect the state of its children.)
? The task assigned to the child is no longer required.
? The parent is exiting, and the operating system does not allow a child to continue if its parent terminates.
進程通信
There are several reasons for providing an environment that allows process cooperation(進程協作):
? Information sharing. Since several users may be interested in the same piece of information (for instance, a shared file), we must provide an environment to allow concurrent access to such information.
? Computation speedup. If we want a particular task to run faster, we must break it into sub-tasks, each of which will be executing in parallel with the others. Notice that such a speedup can be achieved only if the computer has multiple processing cores.
? Modularity. We may want to construct the system in a modular fashion, dividing the system functions into separate processes or threads, as we discussed in Chapter 2.
? Convenience. Even an individual user may work on many tasks at the same time. For instance, a user may be editing, listening to music, and compiling in parallel.
進程需要IPC(進程間通信機制)來允許進程相互交換信息和數據。進程間通信有兩種基本模式:共享內存和消息傳遞。在共享內存的模式中,兩者可以共同讀寫訪問一塊共享的內存區域來交換信息。在消息傳遞模式中,通過進程間交換信息來實現通信。
內存共享比消息傳遞快。消息傳遞系統通常需要系統調用來實現;而在共享內存系統,僅在簡歷共享內存區域的時候需要系統調用,在建立共享內存之後,所有的訪問都是常規的內存訪問。
共享內存系統
生產者-消費者問題:生產者進程產生信息以提供消費者進程消費。比如client-server中,client是生產者而server是消費者。
為了允許生產者進程的消費者進程能並發執行,必須有一個buffer來被生產者填充,冰杯消費者所使用。這個buffer是在生產者進程和消費者進程的共享內存區域內的,當消費者使用一項的時候,生產者進程能產生另外一項,且生產者和消費者必須同步,以免消費者消費一個未被生產出的項。
其中unbounded-buffer是對buffer的大小沒有限制,即消費者可能不得不等待新的項,但是生產者可以不停地生產新的項。bounded-buffer假設buffer大小固定,這樣的話如果buffer為空,那麼消費者必須等待;如果buffer為滿的,那麼生產者必須等待。
推薦閱讀:
※找到Linux虛機Load高的"元兇"
※如何利用秒級監控進行mongodb故障排查
※夏周:阿里雲 Redis 容災體系介紹