標籤:概念 使用者管理 共用資源 系統調用 系統 區分 它的 並且 exit
進程可以說是作業系統最為核心的一個抽象,而線程可以認為是一種輕量級的進程,或者說一個進程內的多個迷你進程。
一、進程的模型
進程(process):進程是一個正在啟動並執行程式的執行個體。對於一個單核的處理器,每個時刻只能運行一個程式,但在每一個時間段,它可能運行多個進程,這樣就產生了並行的錯覺。
從概念上說,每個進程擁有自己的虛擬CPU,好像它獨佔了CPU的使用權一樣,雖然實際的CPU是不斷切換的。進程的另外一大特性,是獨立的虛擬位址空間。
進程的建立
有四種事件導致進程的建立:
(1)系統初始化。系統初始化會建立許多進程,如windows剛開機的時候。
(2)執行了正在啟動並執行進程所調用的系統調用。如程式運行了一個fork()調用。
(3)使用者請求建立一個進程。如命令列中輸入./a.out。
(4)一個批次工作的初始化。
進程的終止
進程是正在啟動並執行程式的執行個體,一個程式是會運行完的,所以進程也有終止的時候:
(1)正常退出(自願)。如程式正常結束。
(2)出錯退出(自願)。如編寫一個程式,當錯誤時調用exit(num)。
(3)嚴重錯誤(非自願)。
(4)被其他進程殺死(非自願)。如另外一個進程調用了kill(pid)。
進程的階層
不同作業系統有不同的概念。Linux系統中區分父進程與子進程,windows系統則不區分。
進程的狀態
進程有三種主要狀態:
(1)運行態:正在CPU上啟動並執行進程。
(2)就緒態:已經就緒但是還沒有被發送器選中。
(3)阻塞態:因為某種原因(如等待I/O完成)暫時無法執行,需要等待外來事件。
下面有一幅圖畫出了可能的轉換關係。需要注意的是,阻塞態的進程必須先進入就緒態,等待處理器的調度。
進程的實現
進程的實現,相對於線程來說是比較確定的。作業系統核心維護一個進程表,也稱為進程式控制制塊(PCB)。進程表項為一個進程啟動的必要資訊,包括進程管理(寄存器,PC,PSW,調度資訊,開啟檔案的狀態等)、儲存管理(程式碼片段、資料區段、堆棧段指標等)、檔案管理(目錄、PID等)資訊。
當進程從運行態進入其他狀態時,PCB儲存著啟動它的所有資訊,當該進程再次被發送器選中時,就要恢複這些資訊。儲存的步驟,包括:硬體壓入PC等,把中斷向量裝入新的PC,然後通過組合語言儲存寄存器並設定新的堆棧,運行中斷服務程式(通常為C),再通過發送器選中一個進程,把它的運行資訊載入寄存器以及PC等。
二、線程的模型
線程的使用,是因為進程建立、撤銷、切換的代價很大,並且需要共用記憶體空間和資料,以及提高運行速度。一個例子是Web伺服器,它如果採用進程的方式,那麼一個頁面請求被響應時,進程就進入了阻塞態,從而無法提供其他服務。而採用線程,可以使用一個線程接受請求,然後把請求指派給背景工作執行緒,實現同時響應,並且共用記憶體。
執行緒模式基於兩個概念:資源分組處理與執行。線程的目的,是共用資源,並共同完成一個任務。
線程與進程非常類似,不過比進程輕量,原因在於:進程擁有獨立的虛擬位址空間,而同一個進程中的線程,共用記憶體空間與資源。因此,線程只需要儲存PC、寄存器、堆棧等,無需儲存大量的檔案、進程管理資訊。線程之間也是沒有保護並且平等的,因為它們共用了同樣的資源,包括開啟的檔案、子進程等。
POSIX(portable operating system interface of UNIX)規定了UNIX系統的通用線程包pthread。
線程的實現
線程的實現,總的來說有兩種:在使用者空間中實現線程,以及在核心中實現線程。
使用者空間中實現線程
這種情況下,核心是不知道線程存在的,調度單位是進程。因此,為了體現多線程的作用,就必須考慮阻塞的問題。
因為使用者管理線程,所以每個進程都要有線程表,與進程表類似,不過記錄的內容比較少。
使用者級線程的優點有很多:
(1)可以在不支援線程的系統上運行。
(2)速度非常快,因為它不需要陷入核心,不需要環境切換,也不需要cache重新整理。
(3)可以允許每個進程定製自己的線程調度演算法。
當然,因為核心不知道線程的存在,需要解決阻塞的問題,可以通過非阻塞系統調用,或者檢查調用是否會阻塞(如select,封裝器)。
另外,因為核心不知道線程的存在,進程內部沒有時鐘中斷,所以線程必須主動讓出CPU,不然其他線程無法搶佔。
核心中實現線程
核心中實現線程,即在核心中維護一個線程表,而進程不維護。與使用者空間中實現相比,優缺點基本是相反的。
核心中的實現,自然不需要非阻塞I/O,但是代價就是,線程的操作花銷很大。
作業系統學習筆記(一) 進程與執行緒模式