天天看點

程序 線程 管程程序管程線程死鎖

程序

定義

程式并不能單獨運作,隻有将程式裝載到記憶體中,系統為它配置設定資源才能運作,而這種執行的程式就稱之為程序。程式和程序的差別就在于:程式是指令的集合,它是程序運作的靜态描述文本;程序是程式的一次執行活動,屬于動态概念。

在多道程式設計中,我們允許多個程式同時加載到記憶體中,在作業系統的排程下,可以實作并發地執行。這是這樣的設計,大大提高了CPU的使用率。程序的出現讓每個使用者感覺到自己獨享CPU,是以,程序就是為了在CPU上實作多道程式設計而提出的。

程序通信的分類

根據程序通信時資訊量大小的不同,可以将程序通信劃分為兩大類型:控制資訊的通信(低級通信)和大批資料資訊的通信(進階通信).

低級通信主要用于程序之間的同步,互斥,終止和挂起等等控制資訊的傳遞.

進階通信主要用于程序間資料塊資料的交換和共享,常見的進階通信有管道,消息隊列,共享記憶體等.

程序間的通信方式

#管道( pipe ):管道是一種半雙工的通信方式,資料隻能單向流動,而且隻能在具有親緣關系的程序間使用.程序的親緣關系一般指的是父子關系.管道一般用于兩個不同程序之間的通信.當一個程序建立了一個管道,并調用fork建立自己的一個子程序後,父程序關閉讀管道端,子程序關閉寫管道端,這樣提供了兩個程序之間資料流動的一種方式.

#有名管道 (named pipe) : 有名管道也是半雙工的通信方式,但是它允許無親緣關系程序間的通信。

# 信号量( semophore ) : 信号量是一個計數器,可以用來控制多個程序對共享資源的通路。它常作為一種鎖機制,防止某程序正在通路共享資源時,其他程序也通路該資源。是以,主要作為程序間以及同一程序内不同線程之間的同步手段。

# 消息隊列( message queue ) : 消息隊列是消息的連結清單,存放在核心中并由消息隊列辨別符辨別.消息隊列克服了信号傳遞資訊少,管道隻能承載無格式位元組流以及緩沖區大小受限等特點.消息隊列是UNIX下不同程序之間可實作共享資源的一種機制,UNIX允許不同程序将格式化的資料流以消息隊列形式發送給任意程序.對消息隊列具有操作權限的程序都可以使用msget完成對消息隊列的操作控制.通過使用消息類型,程序可以按任何順序讀資訊,或為消息安排優先級順序.

# 信号 ( sinal ) : 信号是一種比較複雜的通信方式,用于通知接收程序某個事件已經發生。

# 共享記憶體( shared memory ) :共享記憶體就是映射一段能被其他程序所通路的記憶體,這段共享記憶體由一個程序建立,但多個程序都可以通路。共享記憶體是最快的 IPC 方式,它是針對其他程序間通信方式運作效率低而專門設計的。它往往與其他通信機制,如信号兩,配合使用,來實作程序間的同步和通信。

# 套接字( socket ) : 套解口也是一種程序間通信機制,與其他通信機制不同的是,它可用于不同及其間的程序通信。

各種通信方式的優缺點

幾種通信方法總結綜上所述.程序之間的多種通信方法各自有各自的優點和缺點:如果使用者傳遞的資訊較少.或是需要通過信号來觸發某些行為.前文提到的軟中斷信号機制不失為一種簡捷有效的程序間通信方式.但若是程序間要求傳遞的資訊量比較大或者程序間存在交換資料的要求,那就需要考慮别的通信方式了。無名管道簡單友善.但局限于單向通信的工作方式.并且隻能在建立它的程序及其子孫程序之間實作管道的共享:有名管道雖然可以提供給任意關系的程序使用.但是由于其長期存在于系統之中,使用不當容易出錯.是以普通使用者一般不建議使用。消息緩沖可以不再局限于父子程序.而允許任意程序通過共享消息隊列來實作程序間通信.并由系統調用函數來實作消息發送和接收之間的同步.進而使得使用者在使用消息緩沖進行通信時不再需要考慮同步問題.使用友善,但是消息隊列中資訊的複制需要額外消耗CPU的時間.不适宜于資訊量大或操作頻繁的場合。共享記憶體針對消息緩沖的缺點改而利用記憶體緩沖區直接交換資訊,無須複制,快捷、資訊量大是其優點。但是共享記憶體的通信方式是通過将共享的記憶體緩沖區直接附加到程序的虛拟位址空間中來實作的.是以,這些程序之間的讀寫操作的同步問題作業系統無法實作。必須由各程序利用其他同步工具解決。另外,由于記憶體實體存在于計算機系統中.是以隻能由處于同一個計算機系統中的諸程序共享,不友善網絡通信。不同的程序通信方式有不同的優點和缺點.是以.對于不同的應用問題,要根據問題本身的情況來選擇程序間的通信方式。

一般來說,程序間的通信根據通信内容可以劃分為兩種:即控制資訊的傳送與大批資料傳送。有時也把程序間控制資訊的交換稱為低級通信,而把程序間大批量資料的交換稱為進階通信。

管程

信号量機制雖然是一種既友善又有效的程序同步機制,但是每個通路了解資源的程序都必須自備同步操作,不僅給系統管理帶來麻煩,還很容易因同步操作不當造成系統死鎖。這樣一個新的程序同步工具就出現了——管程。

定義

代表系統共享資源的資料結構,以及有對該共享資料結構實施操作的一組過程所組成的資源管理程式,共同構成一個作業系統的資源管理子產品,我們稱之為“管程”。

管程被請求資源的程序所調用,有四部分組成:①管程的名稱;②局部于管程内部的資料結構的說明;③對該資料結構進行操作的一組過程;④對局部于管程内部的共享資料設定初始值的語句;

管程相當于圍牆,将共享資料結構全部圈了起來,隻留下入口和出口,并且擁有自己的消息隊列,每當程序要通路共享資源的時候,必須經過管程才能進入,而管程每次隻準許一個程序進入管程,進而實作互斥。

管程的特性:

  1. 子產品化。管程是一個基本程式機關,可以獨立編譯。
  2. 抽象資料類型。管程中不僅有資料,還有對資料的操作。
  3. 資訊掩蔽。管程中的資料必須隻能被管程來通路,這些過程也是在管程内部定義的,供管程外的程序調用,而管程中的資料結構以及具體實作外部都是不可見的。

管程與程序的差別:

1、二者雖然都定義的資料結構,但是程序的資料結構PCB是程序私有的,管程的資料結構是公共資料結構,如消息隊列;

2、二者都存在對各自資料結構的操作,但程序是由順序程式執行有關的操作,而管程主要是進行同步操作和資源初始化操作;

3、設定程序的目的就是實作系統的并發性,而管程是解決資源的同步使用問題;

4、程序通過調用管程中的過程來對共享資料結構進行操作,該過程就如同子程式一樣被調用,因而程序的工作方式是主動的,而管程是被動的。

5、程序之間可以并發,但是管程是不能與其調用者并發的

6、程序具有動态性,而管程是作業系統中的一個資源管理子產品,供程序調用。

線程

程序有很多優點,它提供了多道程式設計,讓我們感覺我們每個人都擁有自己的CPU和其他資源,可以提高計算機的使用率。很多人就不了解了,既然程序這麼優秀,為什麼還要線程呢?其實,仔細觀察就會發現程序還是有很多缺陷的,主要展現在兩點上:

程序隻能在一個時間幹一件事,如果想同時幹兩件事或多件事,程序就無能為力了。

程序在執行的過程中如果阻塞,例如等待輸入,整個程序就會挂起,即使程序中有些工作不依賴于輸入的資料,也将無法執行。

如果這兩個缺點了解比較困難的話,舉個現實的例子也許你就清楚了:如果把我們上課的過程看成一個程序的話,那麼我們要做的是耳朵聽老師講課,手上還要記筆記,腦子還要思考問題,這樣才能高效的完成聽課的任務。而如果隻提供程序這個機制的話,上面這三件事将不能同時執行,同一時間隻能做一件事,聽的時候就不能記筆記,也不能用腦子思考,這是其一;如果老師在黑闆上寫演算過程,我們開始記筆記,而老師突然有一步推不下去了,阻塞住了,他在那邊思考着,而我們呢,也不能幹其他事,即使你想趁此時思考一下剛才沒聽懂的一個問題都不行,這是其二。

現在你應該明白了程序的缺陷了,而解決的辦法很簡單,我們完全可以讓聽、寫、思三個獨立的過程,并行起來,這樣很明顯可以提高聽課的效率。而實際的作業系統中,也同樣引入了這種類似的機制——線程。

線程的優點

因為要并發,我們發明了程序,又進一步發明了線程。隻不過程序和線程的并發層次不同:程序屬于在處理器這一層上提供的抽象;線程則屬于在程序這個層次上再提供了一層并發的抽象。如果我們進入計算機體系結構裡,就會發現,流水線提供的也是一種并發,不過是指令級的并發。這樣,流水線、線程、程序就從低到高在三個層次上提供我們所迫切需要的并發!

除了提高程序的并發度,線程還有個好處,就是可以有效地利用多處理器和多核計算機。現在的處理器有個趨勢就是朝着多核方向發展,在沒有線程之前,多核并不能讓一個程序的執行速度提高,原因還是上面所有的兩點限制。但如果講一個程序分解為若幹個線程,則可以讓不同的線程運作在不同的核上,進而提高了程序的執行速度。

例如:我們經常使用微軟的Word進行文字排版,實際上就打開了多個線程。這些線程一個負責顯示,一個接受鍵盤的輸入,一個進行存盤等等。這些線程一起運作,讓我們感覺到我們輸入和螢幕顯示同時發生,而不是輸入一些字元,過一段時間才能看到顯示出來。在我們不經意間,還進行了自動存盤操作。這就是線程給我們帶來的友善之處。

程序與線程的差別

程序是具有一定獨立功能的程式關于某個資料集合上的一次運作活動,程序是系統進行資源配置設定和排程的一個獨立機關。

線程是程序的一個實體, 是CPU排程和分派的基本機關,它是比程序更小的能獨立運作的基本機關.線程自己基本上不擁有系統資源,隻擁有一點在運作中必不可少的資源(如程式計數器,一組寄存器和棧),但是它可與同屬一個程序的其他的線程共享程序所擁有的全部資源。

一個程式至少有一個程序,一個程序至少有一個線程. 一個線程可以建立和撤銷另一個線程,同一個程序中的多個線程之間可以并發執行,線程共享除了堆棧以外的程序資源。 與程序的控制表PCB相似,線程也有自己的控制表TCB,但是TCB中所儲存的線程狀态比PCB表少得多。

程序和線程的主要差别在于它們是不同的作業系統資源管理方式。程序有獨立的位址空間,一個程序崩潰後,在保護模式下不會對其它程序産生影響,而線程隻是一個程序中的不同執行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨的位址空間,一個線程死掉就等于整個程序死掉,是以多程序的程式要比多線程的程式健壯,但在程序切換時,耗費資源較大,效率要差一些。但對于一些要求同時進行并且又要共享某些變量的并發操作,隻能用線程,不能用程序。

死鎖

産生原因

  • 資源競争
  • 程序間推進

産生死鎖的必要條件

  • 互斥
  • 請求和保持
  • 不剝奪
  • 環路等待

預防死鎖

在産生死鎖的必要條件上,加上摒棄(除了互斥條件,因為摒棄互斥,就不能保證并發的正确性了)

  • 摒棄請求和保持

    系統規定所有程序在開始執行之前,都要一次性的申請所需的全部資源。

  • 摒棄環路等待

    所有程序對資源的請求順序必須按照資源号遞增的順序提出。

  • 摒棄不剝奪

    當一個程序已經擁有資源,并且又要請求新的資源的時候不能立即得到滿足,必須立即釋放它原有占有的資源,如果以後還需要此類資源,可以再重新申請。

避免死鎖

銀行家算法來進行死鎖的避免。

檢測死鎖

儲存有關資源的請求和配置設定資訊

提供一種算法,以利用這些資訊來檢測系統是否已進入死鎖狀态

解除死鎖

剝奪資源

撤銷程序

繼續閱讀