【操做系統】進程管理

進程管理git

進程的基本概念

程序的順序執行及其特徵

  1. 程序的順序執行:僅當前一操做(程序段)執行完後,才能執行後續操做。程序員

  2. 程序順序執行時的特徵:順序性,封閉性,可再見性。github

前趨圖

前趨圖(Precedence Graph)是一個有向無循環圖,記爲DAG(Directed Acycilc Graph),用於描述進程之間執行的先後關係。圖中的每個節點可用於描述一個程序段或進程,乃至一條語句。結點間的有向邊則用於表示兩個結點之間存在的偏序(Partial Order)或前趨關係(Precedence Relation)「→」算法

→={(Pi, Pj)|Pi must complete before Pj may start}, 若是(Pi, Pj)∈→,可寫成Pi→Pj,稱Pi是Pj的直接前趨,而稱Pj是Pi的直接後繼。在前趨圖中,把沒有前趨的結點稱爲初始結點(Initial Node),把沒有後繼的結點稱爲終止結點(Final Node)數組

程序的併發執行及其特徵

  1. 程序的併發執行

  1. 程序併發執行時的特徵安全

  • 間斷性網絡

  • 失去封閉性數據結構

  • 不可再現性多線程

進程的特徵和狀態

進程的特徵和定義

結構特徵:併發

  • 動態性

  • 併發性

  • 獨立性

  • 異步性

較典型的進程定義:

  • 進程是程序的一次執行。

  • 進程是一個程序及其數據在處理機上順序執行時所發生的活動。

  • 進程是出如今一個數據集合上運行的過程,它是系統進行資源分配和調度的一個獨立單位。

進程的三種基本狀態

  • 就緒(Ready)狀態

  • 執行狀態

  • 阻塞狀態

掛起狀態

引發掛起狀態的緣由:

  • 終端用戶的請求;

  • 父進程請求;

  • 負責調節的需求;

  • 操做系統的須要

進程狀態的轉換

  • 活動就緒-->靜止就緒

  • 活動阻塞-->靜止阻塞

  • 靜止就緒-->活動就緒

  • 靜止阻塞-->活動阻塞

具備掛起狀態的進程狀態圖

進程控制塊(PCB)

進程控制塊的做用:進程控制塊的做用是使一個在多道程序環境下不能獨立運行的程序(含數據),成爲一個能獨立運行的基本單位,一個能與其它進程併發執行的進程。

進程控制塊中的信息

  • 進程標識符: 進程標識符用於唯一地標識一個進程。一個進程一般有兩種標識符:

    • 內部標識符:在全部的操做系統中,都爲每個進程賦予一個唯一的數字標識符,它一般是一個進程的序號。 設置內部標識符主要是爲了方便系統使用

    • 外部標識符:它由建立者提供,一般是由字母、數字組成,每每是由用戶(進程)在訪問該進程時使用。爲了描述進程的家族關係, 還應設置父進程標識及子進程標識。此外,還可設置用戶標識,以指示擁有該進程的用戶

  • 處理機狀態:處理機狀態信息主要是由處理機的各類寄存器中的內容組成的。

  • 進度調度信息:在PCB中還存放一些與進程調度和進程對換有關的信息,包括:

    • 進程狀態,指明進程的當前狀態,做爲進程調度和對換時的依據

    • 進程優先級,用於描述進程使用處理機的優先級別的一個整數,優先級別高的進程應優先得到處理機

    • 進程調度所需的其它信息,它們與所採用的進程調度算法有關。

    • 事件,是指進程由執行狀態轉變爲阻塞狀態所等待發生的事件,即阻塞緣由。

  • 進程控制信息

    • 程序和數據的地址,是指進程的程序和數據所在的內存或外存地(首)址,以便再調度到該進程執行時,能從PCB中找到其程序和數據

    • 進程同步和通訊機制,指實現進程同步和進程通訊時必需的機制,如信息隊列指針、信號量等,他們可能所有或部分地放在PCB中

    • 資源清單,是一張列出了除CPU之外的、進程所需的所有資源及已經分配到該進程的資源的清單。

    • 連接指針,它給出了本進程(PCB)所在隊列中的下一個進程的PCB的首地址。

進程控制塊的組織方式

  • 連接方式

PCB鏈表隊列示意圖:

  • 索引方式

進程控制

進程的建立

進程圖(Process Graph)

引發建立進程的事件

  • 用戶登陸
  • 做業調度
  • 提供服務
  • 應用請求

進程的建立

  • 申請空白PCB
  • 爲新進程分配資源
  • 初始化進程控制塊
  • 將新進程插入就緒隊列,若是進程就緒隊列可以接納新進程,便將新進程插入就緒隊列。

進程的終止

引發進程終止的事件

  • 正常結束 在任何計算機系統中,都應有一個用於表示進程已經運行完成的指示。
  • 異常結束 在進程運行期間,因爲出現某些錯誤和故障而迫使進程終止。
    • 越界錯誤。這是指程序所訪問的存儲區,已越出該進程的區域;
    • 保護錯。進程試圖去訪問一個不容許訪問的資源或文件,或者以不適當的方式進行訪問,例如,進程試圖去寫一個只讀文件;
    • 非法指令。程序試圖去執行一條不存在的指令。出現該錯誤的緣由,多是程序錯誤地轉移到數據區,把數據當成了指令;
    • 特權指令錯。用戶進程試圖去執行一條只容許OS執行的指令;
    • 運行超時。
    • 等待超時。
    • 算術運算錯。進程試圖去執行一個被禁止的運算,例如,被0除;
    • I/O故障。這是指在I/O過程當中發生了錯誤等
  • 外界干預 外界干預並不是指在本進程運行中出現了異常事件,而是指進程應外界的請求而終止運行。
    • 操做員或操做系統干預
    • 父進程請求
    • 父進程終止

進程的終止過程

  1. 根據被終止進程的標識符,從PCB集合中檢索出該進程的PCB,從中讀出該進程的狀態
  2. 若被終止進程正處於執行狀態,應當即終止該進程的執行,並置調度標誌爲真,用於指示該進程被終止後應從新進行調度
  3. 若該進程還有子孫進程,還應將其全部子孫進程予以終止,以防他們成爲不可控的進程
  4. 將被終止進程所擁有的所有資源,或者歸還給其父進程, 或者歸還給系統
  5. 將被終止進程(它的PCB)從所在隊列(或鏈表)中移出, 等待其餘程序來蒐集信息

 進程的阻塞與喚醒

引發進程阻塞和喚醒的事件

  • 請求系統服務
  • 啓動某種操做
  • 新數據還沒有到達
  • 無工做可作

進程阻塞過程

正在執行的進程,當發現上述某事件時,因爲沒法繼續執行,因而進程便經過調用阻塞原語block把本身阻塞。可見,進程的阻塞是進程自身的一種主動行爲。進入block過程後,因爲此時該進程還處於執行狀態,因此應先當即中止執行,把進程控制塊中的現行狀態由「執行」改成阻塞,並將PCB插入阻塞隊列。若是系統中設置了因不一樣事件而阻塞的多個阻塞隊列,則應將本進程插入到具備相同事件的阻塞(等待)隊列。 最後,轉調度程序進行從新調度,將處理機分配給另外一就緒進程,並進行切換,亦即,保留被阻塞進程的處理機狀態(在PCB中),再按新進程的PCB中的處理機狀態設置CPU的環境。

進程喚醒過程

當被阻塞進程所期待的事件出現時,如I/O完成或其所期待的數據已經到達,則由有關進程(好比,用完並釋放了該I/O設備的進程)調用喚醒原語wakeup( ),將等待該事件的進程喚醒。

原語執行的過程是:首先把被阻塞的進程從等待該事件的阻塞隊列中移出,將其PCB中的現行狀態由阻塞改成就緒,而後再將該PCB插入到就緒隊列中

進程的掛起與激活

  1. 進程的掛起 當被阻塞進程所期待的事件出現時,如I/O完成或其所期待的數據已經到達,則由有關進程(好比,用完並釋放了該I/O設備的進程)調用喚醒原語wakeup( ),將等待該事件的進程喚醒。 >喚醒原語執行的過程是:首先把被阻塞的進程從等待該事件的阻塞隊列中移出,將其PCB中的現行狀態由阻塞改成就緒,而後再將該PCB插入到就緒隊列中
  2. 進程的激活過程 當發生激活進程的事件時,例如,父進程或用戶進程請求激活指定進程,若該進程駐留在外存而內存中已有足夠的空間時,則可將在外存上處於靜止就緒狀態的進程換入內存。這時,系統將利用激活原語active( )將指定進程激活。 >激活原語先將進程從外存調入內存,檢查該進程的現行狀態,如果靜止就緒,便將之改成活動就緒;若爲靜止阻塞便將之改成活動阻塞。假如採用的是搶佔調度策略,則每當有新進程進入就緒隊列時,應檢查是否要進行從新調度,即由調度程序將被激活進程與當前進程進行優先級的比較,若是被激活進程的優先級更低,就沒必要從新調度;不然,當即剝奪當前進程的運行,把處理機分配給剛被激活的進程。

進程同步

進程同步的主要任務是對多個相關進程在執行次序上進行協調,以使併發執行的諸進程之間能有效地共享資源和相互合做,從而使程序的執行具備可再現性。

進程同步的基本概念

  1. 兩種形式的制約關係
    • 間接相互制約關係,源於資源共享。
    • 直接相互制約關係,源於進程間的合做。
  2. 臨界資源(Critical Resouce) 許多硬件資源如打印機、磁帶機等,都屬於臨界資源,諸進程間應採起互斥方式,實現對這種資源的共享。

    生產者-消費者(producer-consumer)問題:有一羣生產者進程在生產產品,並將這些產品提供給消費者進程去消費。爲使生產者進程與消費者進程能併發執行,在二者之間設置了一個具備n個緩衝區的緩衝池,生產者進程將它所生產的產品放入一個緩衝區中; 消費者進程可從一個緩衝區中取走產品去消費。儘管全部的生產者進程和消費者進程都是以異步方式運行的,但它們之間必須保持同步,即不容許消費者進程到一個空緩衝區去取產品;也不容許生產者進程向一個已裝滿產品且還沒有被取走的緩衝區中投放產品。

    咱們可利用一個數組來表示上述的具備n個(0,1,…,n-1)緩衝區的緩衝池。用輸入指針in來指示下一個可投放產品的緩衝區,每當生產者進程生產並投放一個產品後,輸入指針加1;用一個輸出指針out來指示下一個可從中獲取產品的緩衝區,每當消費者進程取走一個產品後,輸出指針加1。 因爲這裏的緩衝池是組織成循環緩衝的,故應把輸入指針加1表示成 in∶=(in+1)mod n;輸出指針加1表示成out∶=(out+1) mod n。當(in+1) mod n=out時表示緩衝池滿;而in=out則表示緩衝池空。此外,還引入了一個整型變量counter, 其初始值爲0。每當生產者進程向緩衝池中投放一個產品後,使counter加1;反之,每當消費者進程從中取走一個產品時, 使counter減1。生產者和消費者兩進程共享下面的變量:

    Var n, integer;
    type item=…;
    var buffer:array[0, 1, …, n-1] of item;
    in, out: 0, 1, …, n-1;
    counter: 0, 1, …, n;

    指針in和out初始化爲1。在生產者和消費者進程的描述中,no-op是一條空操做指令,while condition do no-op語句表示重複的測試條件(condication),重複測試應進行到該條件變爲false(假),即到該條件不成立時爲止。在生產者進程中使用一局部變量nextp,用於暫時存放每次剛生產出來的產品;而在消費者進程中,則使用一個局部變量nextc,用於存放每次要消費的產品。 producer: repeat ... produce an item in nextp; ... while counter=n do no-op; buffer[in]:=nextp; in:=(in+1)mod n; counter: =counter+1; until false; consumer: repeat while counter=0 do no-op; nextc: =buffer[out]; out: =(out+1) mod n; counter: =counter-1; consumer the item in nextc; until false;

    雖然上面的生產者程序和消費者程序,在分別看時都是正確的,並且二者在順序執行時其結果也會是正確的,但若併發執行時,就會出現差錯,問題就在於這兩個進程共享變量counter。生產者對它作加1操做,消費者對它作減1操做,這兩個操做在用機器語言實現時, 常可用下面的形式描述:

    register 1:=counter; register 2:=counter;
    register1:=register 1+1; register 2:=register 2-1;
    counter:=register 1; counter: =register 2;

    假設:counter的當前值是5。若是生產者進程先執行左列的三條機器語言語句,而後消費者進程再執行右列的三條語句, 則最後共享變量counter的值仍爲5;反之,若是讓消費者進程先執行右列的三條語句,而後再讓 生產者進程執行左列的三條語句,counter值也仍是5,可是,若是按下述順序執行: register 1 :=counter; (register 1=5) register 1 :=register 1+1; (register 1=6) register 2 :=counter; (register 2=5) register 2 :=register 2-1; (register 2=4) counter :=register 1; (counter=6) counter :=register 2; (counter=4)

    正確的counter值應該是5,可是如今是4.爲了預防產生這種錯誤,解決此問題的關鍵是應把變量counter做爲臨界資源處理,即,令生產者進程和消費者進程互斥地訪問變量counter。

  3. 臨界區(critical section) 可把一個訪問臨界資源的循環進程描述以下: 

  4. 同步機制應遵循的規則

    • 空閒讓進
    • 忙則等待
    • 有限等待
    • 讓權等待

信號量機制

整型信號量

最初由Dijkstra把整型信號量定義爲一個用於表示資源數目的整型量S,除初始化外,僅能經過兩個標準的原子操做(Atomic Operation) wait(S)和signal(S)來訪問。 這兩個操做被分別稱爲P、V操做。 wait和signal操做可描述爲:

wait(S): while S≤0 do no-op;
        S:=S-1;
signal(S):S:=S+1;

記錄型信號量

在信號量機制中,除了須要一個用於表明資源數目的整型變量value外,還應增長一個進程鏈表L,用於連接等待進程。記錄型信號量是因爲它採用了記錄型的數據結構而得名的。它所包含的上述兩個數據項可描述爲:

type semaphore=record
     value:integer;
     L:list of process;
     end

相應地,wait(S)和signal(S)操做可描述爲:

procedure wait(S)
 var S: semaphore;
 begin
   S.value∶   =S.value-1;
   if S.value<0 then
   block(S,L)
 end
procedure signal(S)
 var S: semaphore;
 begin
  S.value∶   =S.value+1;
  if S.value≤0 then
  wakeup(S,L);
 end

在記錄型信號量機制中,S.value的初值表示系統中某類資源的數目, 於是又稱爲資源信號量,對它的每次wait操做,意味着進程請求一個單位的該類資源,所以描述爲S.value∶ =S.value-1; 當S.value<0時,表示該類資源已分配完畢,所以進程應調用block原語,進行自我阻塞,放棄處理機,並插入到信號量鏈表S.L中。可見,該機制遵循了「讓權等待」準則。 此時S.value的絕對值表示在該信號量鏈表中已阻塞進程的數目。 對信號量的每次signal操做,表示執行進程釋放一個單位資源,故S.value∶ =S.value+1操做表示資源數目加1。 若加1後還是S.value≤0,則表示在該信號量鏈表中,仍有等待該資源的進程被阻塞,故還應調用wakeup原語,將S.L鏈表中的第一個等待進程喚醒。若是S.value的初值爲1,表示只容許一個進程訪問臨界資源,此時的信號量轉化爲互斥信號量。

AND型信號量

AND同步機制的基本思想是:將進程在整個運行過程當中須要的全部資源,一次性所有地分配給進程,待進程使用完後再一塊兒釋放。只要尚有一個資源未能分配給進程,其它全部可能爲之分配的資源,也不分配給他。亦即,對若干個臨界資源的分配,採起原子操做方式:要麼所有分配到進程,要麼一個也不分配。 由死鎖理論可知,這樣就可避免上述死鎖狀況的發生。爲此,在wait操做中,增長了一個「AND」條件,故稱爲AND同步,或稱爲同時wait操做, 即Swait(Simultaneous wait)定義以下:

Swait(S1, S2, …, Sn)
if Si≥1 and … and Sn≥1 then
    for i∶ =1 to n do
    Si∶=Si-1;
    endfor
else
 place the process in the waiting queue associated with the first Si found   with Si<1, and set the program count of this process to the beginning of Swait operation
endif
Ssignal(S1, S2, …, Sn)
  for i∶   =1 to n do
  Si=Si+1;
  Remove all the process waiting in the queue associated with Si into the ready queue.
endfor;

信號量集

通常「信號量集」的幾種特殊狀況: (1) Swait(S, d, d)。 此時在信號量集中只有一個信號量S, 但容許它每次申請d個資源,當現有資源數少於d時,不予分配。 (2) Swait(S, 1, 1)。 此時的信號量集已蛻化爲通常的記錄型信號量(S>1時)或互斥信號量(S=1時)。 (3) Swait(S, 1, 0)。這是一種很特殊且頗有用的信號量操做。當S≥1時,容許多個進程進入某特定區;當S變爲0後,將阻止任何進程進入特定區。換言之,它至關於一個可控開關。

信號量的應用

  1. 利用信號量實現進程互斥 Var mutex:semaphore:=1; begin parbegin process 1: begin repeat wait(mutex); critical section signal(mutex); remainder seetion until false; end process 2: begin repeat wait(mutex); critical section signal(mutex); remainder section until false; end parend
  2. 利用信號量實現前趨關係 設有兩個併發執行的進程P1和P2.P1中有語句S1;P2中有語句S2。咱們但願在S1執行後再執行S2,爲實現這種前趨關係,咱們只需使進程P1和P2共享一個公共信號值S,並賦予其初值爲0,將signal(S)操做放在語句S1後面;而在S2語句前面插入wait(S)操做,即 在進程P1中,用S1: signal(S); 在進程P2中,用wait(S);S2; 因爲S被初始化爲0,這樣,若P2先執行一定阻塞,只有在進程P1執行完S1;signal(S);操做後使S增爲1時,P2進程方能執行語句S2成功。

管程機制

管程(Monitors):一種新的進程同步工具 1. 管程的定義 管程由四部分組成: - 管程的名稱、 - 局部於管程內部的分享數據結構說明、 - 對該數據進行操做的一組過程、 - 對局部於管程內部的共享數據設置初始值的語句。

管程至關於圍牆,它把共享變量和對它進行操做的若干過程圍了起來,全部進程要訪問臨界資源時,都必須通過管程(至關於經過圍牆的門)才能進入,而管程每次只准許一個進程進入管程,從而實現了進程互斥。 管程的特性:

  • 模塊化
  • 抽象數據類型
  • 信息掩蔽

2.條件變量 考慮一種狀況:當一個進程調用了管程,在管程中時被阻塞或掛起,直到阻塞或掛起的緣由解除,而在此期間,若是該進程不釋放管程,則其餘進程沒法進入管程,被迫長時間地等待。爲了解決這個問題,引入了條件變量condition。對這些條件變量的訪問,只能在管程中進行。 管程中對每個條件變量都需予以說明,其形式爲:Var x,y:condition。對條件變量的操做僅僅是wait和signal,所以條件變量也是一種抽象數據類型,每一個條件變量保存了一個鏈表,用來記錄因該條件變量而阻塞的全部進程,同時提供的兩個操做便可表示爲x.wait和x.signal。其含義爲

  • x.wait:正在調用管程的進程因x條件須要被阻塞或掛起,則調用x.wait將本身插入到x條件的等待隊列上,並釋放管程,直到x條件變化。此時其餘進程可使用該管程。
  • x.signal:正在調用管程的進程發現x條件發生了變化,則調用x.signal,從新啓動一個因x條件而阻塞或掛起的進程。若是存在多個這樣的進程,則選擇其中一個,若是沒有,則繼續執行原進程,而不產生任何結果。這和信號量機制中的signal操做不一樣,由於後者總要執行s:=s+1操做,於是總會改變信號量的狀態。 若是有進程Q因x條件處於阻塞狀態,當正在調用管程的進程P執行了x.signal操做後,進程Q被從新啓動了。此時兩個進程P和Q,如何肯定那個執行,哪一個等待,可採用下述兩種方式之一進行處理:
    • P等待,直至Q離開管程或等待另外一條件
    • Q等待,直至P離開管程或等待另外一條件

進程通訊

信號量機制做爲同步工具是卓有成效的,但做爲通訊工具,則不夠理想,主要表如今兩個方面:

  • 效率低
  • 通訊對用戶不透明

本節所介紹的是高級進程通訊,是指用戶可直接利用操做系統所提供的一組通訊命令高效地傳送大量數據的一種通訊方式。操做系 統隱藏了進程通訊的實現細節。即通訊過程對用戶是透明的,這樣就大大減小了通訊程序編制上的複雜性。

進程通訊的類型

目前,高級通訊機制可歸結爲三大類:共享存儲器系統、消息傳遞系統以及管道通訊系統。 1. 共享存儲器系統 在共享存儲器系統(Shared-Memory System)中,相互通訊的進程共享某些數據結構或共享數據存儲區,進程之間可以經過這些空間進行通訊。 1. 基於共享數據結構的通訊方式。 在這種通訊方式中,要求諸進程公用某些數據結構,藉以實現諸進程間的信息交換。這種通訊方式是低效的,只適於傳遞相對少許的數據。 2. 基於共享存儲區的通訊方式 爲了傳輸大量數據、在存儲器中劃出了一塊共享存儲區,諸進程可經過對共享存儲區中數據的讀或寫來實現通訊。進程在通訊前,先向系統申請得到共享存儲區中的一個分區,並指定該分區的關鍵字;若系統已經給其餘進程分配了這樣的分區,則將該分區的描述符返回給申請者,繼之,由申請者把得到的共享存儲區鏈接到本進程中;此後,即可像讀、寫普通存儲器同樣地讀、寫該公用存儲分區。 2. 消息傳遞系統 消息傳遞系統(Message passing system)是當前應用最普遍的一種進程間的通訊機制。在該機制中,進程間的數據交換是以格式化的消息(message)爲單位的;在計算機網絡中又把message稱爲報文。程序員直接利用操做系統提供的一組通訊命令(原語),不只能實現大量數據的傳遞,並且還隱藏了通訊的實現細節,是通訊過程對用戶是透明的,從而大大減化了通訊程序編制的複雜性。 3. 管道通訊 所謂"管道",是指用於鏈接一個讀進程和一個寫進程以實現它們之間通訊的一個共享文件,又名pipe文件。向管道(共享文件)提供輸入

線程

線程的基本概念

進程的操做

  1. 建立進程
  2. 撤消進程
  3. 進程切換

線程的屬性

  1. 輕型實體
  2. 獨立調度和分派的基本單位
  3. 可並行執行
  4. 共享進程資源

線程的狀態

狀態參數

在OS中的每個線程均可以利用線程標識符和一組狀態參數進行描述。狀態參數一般有這樣幾項:

  • 寄存器狀態,包括程序計數器PC和堆棧指針中的內容;
  • 堆棧,在堆棧中一般保存有局部變量和返回地址
  • 線程運行狀態,用於描述線程正處於何種運行狀態
  • 優先級,描述線程執行的優先程序
  • 線程專有存儲器,用於保存線程本身的局部變量拷貝
  • 信號屏蔽,即對某些信號加以屏蔽

線程運行狀態

線程在運行時,具備三種基本狀態:

  • 執行狀態,表示線程正得到處理機而運行;
  • 就緒狀態,指線程已具有了各類執行條件,一旦得到CPU即可執行的狀態
  • 阻塞狀態,指線程在執行中因某事件而受阻,處於暫停執行時的狀態

線程的建立和終止

在多線程OS環境下,應用程序在啓動時,一般僅有一個線程在執行,該線程被人們稱爲「初始化線程」。它可根據須要再去建立若干個線程。在建立新線程時,須要利用一個線程建立函數(或系統調用),並提供相應的參數,如指向線程主程序的入口指針、堆棧的大小,以及用於調度的優先級等。在線程建立函數執行完後,將返回一個線程標識符供之後使用。 終止線程的方式有兩種:一種是在線程完成了本身的工做後自願退出;另外一種是線程在運行中出現錯誤或因爲某種緣由而被其它線程強行終止。

多線程OS中的進程

在多線程OS中,進程是做爲擁有系統資源的基本單位,一般的進程都包含多個線程併爲它們提供資源,但此時的進程就再也不做爲一個執行的實體。 多線程OS中的進程有如下屬性: 1. 做爲系統資源分配的單位 2. 可包括多個線程 3. 進程不是一個可執行的實體

線程間的同步和通訊

  1. 互斥鎖(mutex) 互斥鎖是一種比較簡單的、用於實現進程間對資源互斥訪問的機制。因爲操做互斥鎖的時間和空間開鎖都較低, 於是較適合於高頻度使用的關鍵共享數據和程序段。互斥鎖能夠有兩種狀態, 即開鎖(unlock)和關鎖(lock)狀態。 相應地,可用兩條命令(函數)對互斥鎖進行操做。其中的關鎖lock操做用於將mutex關上,開鎖操做unlock則用於打開mutex。
  2. 條件變量 每個條件變量一般都與一個互斥鎖一塊兒使用,亦即,在建立一個互斥鎖時便聯繫着一個條件變量。單純的互斥鎖用於短時間鎖定,主要是用來保證對臨界區的互斥進入。而條件變量則用於線程的長期等待, 直至所等待的資源成爲可用的。 線程首先對mutex執行關鎖操做,若成功便進入臨界區,而後查找用於描述資源狀態的數據結構,以瞭解資源的狀況。 只要發現所需資源R正處於忙碌狀態,線程便轉爲等待狀態, 並對mutex執行開鎖操做後,等待該資源被釋放; 若資源處於空閒狀態,代表線程可使用該資源,因而將該資源設置爲忙碌狀態,再對mutex執行開鎖操做。 下面給出了對上述資源的申請(左半部分)和釋放(右半部分)操做的描述: Lock mutex Lock mutex check data structures; mark resource as free; while(resource busy); unlock mutex; wait(condition variable); wakeup(condition variable); mark resource as busy; unlock mutex;
  3. 信號量機制
  4. 私有信號量(private samephore) 當某線程需利用信號量來實現同一進程中各線程之間的同步時,可調用建立信號量的命令來建立一私用信號量,其數據結構是存放在應用程序的地址空間中。私用信號量屬於特定的進程全部,OS並不知道私用信號量的存在,所以,一旦發生私用信號量的佔用者異常結束或正常結束,但並未釋放該信號量所佔有空間的狀況時,系統將沒法使它恢復爲0(空), 也不能將它傳送給下一個請求它的線程。
  5. 公有信號量(public samephore) 公用信號量是爲實現不一樣進程間或不一樣進程中各線程之間的同步而設置的。因爲它有着一個公開的名字供全部的進程使用,故而把它稱爲公用信號量。其數據結構是存放在受保護的系統存儲區中,由OS爲它分配空間並進行管理,故也稱爲系統信號量。若是信號量的佔有者在結束時未釋放該公用信號量,則OS會自動將該信號量空間回收,並通知下一進程。可見,公用信號量是一種比較安全的同步機制。 ##內核支持線程和用戶級線程
  6. 內核支持線程 這裏所謂的內核支持線程,也都一樣是在內核的支持下運行的,即不管是用戶進程中的線程,仍是系統進程中的線程,他們的建立、撤消和切換等,也是依靠內核實現的。此外,在內核空間還爲每個內核支持線程設置了一個線程控制塊, 內核是根據該控制塊而感知某線程的存在的,並對其加以控制。

  7. 用戶級線程 用戶級線程僅存在於用戶空間中。對於這種線程的建立、 撤消、線程之間的同步與通訊等功能,都無須利用系統調用來實現。對於用戶級線程的切換,一般是發生在一個應用進程的諸多線程之間,這時,也一樣無須內核的支持。因爲切換的規則遠比進程調度和切換的規則簡單,於是使線程的切換速度特別快。可見,這種線程是與內核無關的。

線程控制

內核支持線程的實現

用戶級線程的實現

  1. 運行時系統(Runtime System) 所謂「運行時系統」,實質上是用於管理和控制線程的函數(過程)的集合, 其中包括用於建立和撤消線程的函數、 線程同步和通訊的函數以及實現線程調度的函數等。正由於有這些函數,才能使用戶級線程與內核無關。運行時系統中的全部函數都駐留在用戶空間,並做爲用戶級線程與內核之間的接口。
  2. 內核控制線程 這種線程又稱爲輕型進程LWP(Light Weight Process)。 每個進程均可擁有多個LWP, 同用戶級線程同樣, 每一個LWP都有本身的數據結構(如TCB),其中包括線程標識符、優先級、 狀態, 另外還有棧和局部存儲區等。 它們也能夠共享進程所擁有的資源。LWP可經過系統調用來得到內核提供的服務,這樣,當一個用戶級線程運行時,只要將它鏈接到一個LWP上,此時它便具備了內核支持線程的全部屬性。 
相關文章
相關標籤/搜索