程序和執行緒
作業系統中核心的概念是程序:這是對正在執行程式的一個抽象。 沒有程序的抽象,現代計算將不復存在。 ----《現代作業系統》第四版 機械工業出版社
(從這本書的作者中我們就可以產出作為一個學計算機專業出生的人罪域程序的理解是多麼的重要,上學期學作業系統這門課的時候並沒有總結,今天終於下定決心總結下了,因為實在是感覺太重要了。在描述一些重要的概念的時候我還是會借鑑書上的文字,害怕自己總結的有錯。)
程序
在書中程序的定義是:
在任何多道程式設計系統中,CPU由一個程序快速切換成另一個程序,使每個程序各執行幾十或者幾百毫秒。嚴格的說,在某一個瞬間,CPU只能執行一個程序。但在一秒內,它可能執行多個程序,這樣就產生並行的錯覺,有時人們所說的 偽並行 就是指的這樣情況,以此來區分多處理器系統(該系統有兩或多個CPU共享同一實體記憶體)的真正硬體並行。人們很難對多個並行活動進行跟蹤,以此經過多年的努力,作業系統的設計者開發了用於描述並行的一種概念模型( 順序程序 ),使得並行更容易處理。
在程序模型中,計算機上所有課執行的軟體,通常也包括作業系統,被組織成若干 順序程序 (sequential process),簡稱 程序 。
從概念上講,每個程序擁有它自己的虛擬CPU。當然,實際上真正的CPU在多個程序間來回切換。
程序的定義(以前老師給我們總結)
1、程序是程式作用在一組資料上的一次執行。
2、程序是作業系統中一個可獨立排程和資源分配的基本單位(不是最小而是基本單位)。
3、程序是可以和別的計算併發執行的計算。
舉個例子:
程序和程式間的區別是很微妙的,但非常重要。用一個比喻可以更容易理解這一點。想象一位有一手好廚藝的電腦科學家正在為他的女兒烘製生日蛋糕。他有做生日蛋糕的食譜,廚房有所需的原料,做蛋糕的食譜就是程式(即用適當形式描述的演算法),電腦科學家就是處理器(CPU),而做蛋糕的各種原料就是輸入資料。程序就是廚師閱讀食譜、取來各種原料以及烘製蛋糕等一系列動作的總和。
程序的狀態
程序有三個基本狀態: 就緒狀態
、 執行狀態
與 阻塞狀態
。
程序在執行的時候必處於這三個狀態中的之一。

就緒狀態
:程序獲得必要資源,例如記憶體等,已經具備了執行條件,只是沒有空閒的CPU,處於等待CPU的狀態。在系統中,將處於就緒狀態的多個程序的PCB表排成一個佇列,或按照某種規則排在不同的佇列中,這些佇列稱為就緒佇列。
執行狀態
:程序已經獲得必要的資源及CPU,它的程式正在執行中,這時程序的狀態稱為執行狀態。在多處理機系統中,可以有多個程序處於執行狀態。在單處理機系統中,只能有一個程序處於執行狀態,系統應儘量保證一個CPU上總有一個處於執行狀態的程序,使CPU得到充分的利用。
阻塞狀態
:程序因某等待事件發生(例如I/O請求、某些原語操作等)而處於暫停執行的狀態,此時即使將CPU分配給它,它的程式也無法執行。在系統中,將處於阻塞狀態的程序的PCB表排成一個佇列,或因阻塞原因不同而將程序的PCB表排在不同的佇列中,這些佇列稱為阻塞佇列。
程序的狀態轉換

程序有四種狀態變遷:
- 就緒→執行
排程程式選擇這個程序 - 執行→就緒
排程程式選擇另外一個程序 - 執行→阻塞
程序因為等待資源而被阻塞 - 阻塞→就緒
Linux程序有父程序、子程序, Windows的程序是平等關係。
執行緒
程序擁有資源,屬於同一個程序的所有執行緒可以共享這些資源。此外,每個執行緒僅有較少的私用資源,如程式計數器、暫存器和棧等。
每一個執行緒是一個動態物件,它表示程序中的一條控制線索,執行一系列指令操作,是一個相對獨立的、可被排程執行的基本單位。
執行緒由建立而產生,由撤消而消亡,在生命期間,執行緒可以處於就緒狀態、執行狀態和阻塞狀態三個基本狀態中。
這三個基本狀態也像程序一樣,會發生變遷,如就緒狀態→執行狀態,執行狀態→阻塞狀態,阻塞狀態→就緒狀態等。
不同型別的執行緒有著不同的屬性和使用方法,三種主要的執行緒型別:
-
核心執行緒
一個核心執行緒可以獨立工作,不需要與一個使用者程序聯絡起來。 -
輕量級程序LWP
-
一個輕量級程序LWP是一個核心支援的使用者執行緒,執行在使用者空間。
-
核心執行緒基礎上的高層抽象,因此……
-
每個程序可以有一個或多個輕量級程序LWP,使用者程序通過輕量級程序LWP與
核心通訊,每一個輕量級程序LWP都由一個單獨的核心執行緒支援。
-
可以被排程並且共享所屬程序的地址空間和其它資源。
-
它們可以對I/O裝置或其它資源進行系統呼叫,同時也能在I/O操作或資源訪問時被阻塞。
-
除了核心堆疊和暫存器外,輕量級程序LWP也需要維護一些使用者狀態,主要包括使用者暫存器上下文,當輕量級程序LWP被搶佔CPU時這些內容必須儲存下來,以便保證下次排程執行的正確進行。
-
為了節省系統開銷,多個使用者程序可以多路複用一個輕量級程序LWP,但是隻有連線到輕量級程序LWP的程序,才能與核心通訊。
程序、輕量級程序LWP及核心執行緒關係圖
-
使用者執行緒
使用者執行緒執行在使用者空間,核心無需也無法感知它。每個使用者執行緒僅需一個棧和程式計數器PC, 切換速度快。當一個使用者執行緒被阻塞時, 它在停止之前選擇並啟動它的後繼執行緒。
使用者執行緒的實現是可能的,因為使用者執行緒的上下文可以在沒有核心干預的情況下被儲存和恢復。每一個使用者執行緒有自己的使用者堆疊,一塊用來儲存使用者級暫存器上下文以及如訊號遮蔽等狀態資訊的記憶體區域。通過儲存當前執行緒的堆疊和暫存器內容,以及裝入新排程執行緒的那些堆疊和暫存器內容,可實現使用者執行緒間的排程和上下文的切換。
核心仍然負責程序的切換,因為只有核心具有修改記憶體管理暫存器的權力。使用者執行緒不是真正地可以排程的實體,核心沒有保留它們的一點資訊,核心只是簡單地排程它們下面的程序,這些程序再使用庫函式來排程它們的執行緒。當程序被搶佔時,它們的執行緒也被搶佔。

普通程序上的使用者執行緒
程序和執行緒的比較
在引入執行緒的作業系統中,不僅程序之間可以併發執行,而且屬於同一個程序的多個執行緒之間也可以併發執行,因而使系統具有更好的併發性,可以更有效地使用系統資源和提高系統的吞吐量。
無論是傳統的作業系統,還是引入執行緒的作業系統,程序都是擁有資源的一個獨立單位,而執行緒僅擁有很少的一些私有資源(如程式計數器、暫存器和棧、執行緒表項等),但是它可以訪問所屬程序的所有資源。
在程序建立和程序撤消時,系統所付出的開銷大於建立執行緒和撤消執行緒的開銷。程序切換的開銷遠遠大於執行緒切換的開銷。此外,由於同一程序的多個執行緒具有相同的地址空間,使得它們之間的同步和通訊也變得比較容易實現。
如果要學習更多的作業系統的只是,我推薦看《現代作業系統》第四版 Andrew S.Tanenbaum 和 Herbert Bos 著