進程/線程同步的方式和機制,進程間通訊

http://blog.csdn.net/deppcyan/article/details/8169526數據庫

 

1、進程/線程間同步機制。編程

臨界區、互斥區、事件、信號量四種方式
臨界區(Critical Section)、互斥量(Mutex)、信號量(Semaphore)、事件(Event)的區別
一、臨界區:經過對多線程的串行化來訪問公共資源或一段代碼,速度快,適合控制數據訪問。在任意時刻只容許一個線程對共享資源進行訪問,若是有多個線程試圖訪問公共資源,那麼在有一個線程進入後,其餘試圖訪問公共資源的線程將被掛起,並一直等到進入臨界區的線程離開,臨界區在被釋放後,其餘線程才能夠搶佔。
二、互斥量:採用互斥對象機制。 只有擁有互斥對象的線程纔有訪問公共資源的權限,由於互斥對象只有一個,因此能保證公共資源不會同時被多個線程訪問。互斥不只能實現同一應用程序的公共資源安全共享,還能實現不一樣應用程序的公共資源安全共享 .互斥量比臨界區複雜。由於使用互斥不只僅可以在同一應用程序不一樣線程中實現資源的安全共享,並且能夠在不一樣應用程序的線程之間實現對資源的安全共享。
三、信號量:它容許多個線程在同一時刻訪問同一資源,可是須要限制在同一時刻訪問此資源的最大線程數目 .信號量對象對線程的同步方式與前面幾種方法不一樣,信號容許多個線程同時使用共享資源,這與操做系統中的PV操做相同。它指出了同時訪問共享資源的線程最大數目。它容許多個線程在同一時刻訪問同一資源,可是須要限制在同一時刻訪問此資源的最大線程數目。安全

PV操做及信號量的概念都是由荷蘭科學家E.W.Dijkstra提出的。信號量S是一個整數,S大於等於零時表明可供併發進程使用的資源實體數,但S小於零時則表示正在等待使用共享資源的進程數。
   P操做申請資源:
  (1)S減1;
  (2)若S減1後仍大於等於零,則進程繼續執行;
  (3)若S減1後小於零,則該進程被阻塞後進入與該信號相對應的隊列中,而後轉入進程調度。
  
  V操做 釋放資源:
  (1)S加1;
  (2)若相加結果大於零,則進程繼續執行;
  (3)若相加結果小於等於零,則從該信號的等待隊列中喚醒一個等待進程,而後再返回原進程繼續執行或轉入進程調度。
四、事 件: 經過通知操做的方式來保持線程的同步,還能夠方便實現對多個線程的優先級比較的操做 .多線程

 

總結:
  1. 互斥量與臨界區的做用很是類似,但互斥量是能夠命名的,也就是說它能夠跨越進程使用。因此建立互斥量須要的資源更多,因此若是隻爲了在進程內部是用的話使用臨界區會帶來速度上的優點並可以減小資源佔用量。由於互斥量是跨進程的互斥量一旦被建立,就能夠經過名字打開它。
  2. 互斥量(Mutex),信號燈(Semaphore),事件(Event)均可以被跨越進程使用來進行同步數據操做,而其餘的對象與數據同步操做無關,但對於進程和線程來說,若是進程和線程在運行狀態則爲無信號狀態,在退出後爲有信號狀態。因此可使用WaitForSingleObject來等待進程和線程退出。
  3. 經過互斥量能夠指定資源被獨佔的方式使用,但若是有下面一種狀況經過互斥量就沒法處理,好比如今一位用戶購買了一份三個併發訪問許可的數據庫系統,能夠根據用戶購買的訪問許可數量來決定有多少個線程/進程能同時進行數據庫操做,這時候若是利用互斥量就沒有辦法完成這個要求,信號燈對象能夠說是一種資源計數器。併發

 

2、進程間通訊方式socket

因爲比較容易混淆,咱們把進程間通訊方法也列在這裏作比較。測試

程間通訊就是在不一樣進程之間傳播或交換信息,那麼不一樣進程之間存在着什麼雙方均可以訪問的介質呢?進程的用戶空間是互相獨立的,通常而言是不能互相訪問的,惟一的例外是共享內存區。可是,系統空間倒是「公共場所」,因此內核顯然能夠提供這樣的條件。除此之外,那就是雙方均可以訪問的外設了。在這個意義上,兩個進程固然也能夠經過磁盤上的普通文件交換信息,或者經過「註冊表」或其它數據庫中的某些表項和記錄交換信息。廣義上這也是進程間通訊的手段,可是通常都不把這算做「進程間通訊」。由於那些通訊手段的效率過低了,而人們對進程間通訊的要求是要有必定的實時性。操作系統

 

  進程間通訊主要包括管道, 系統IPC(包括消息隊列,信號量,共享存儲), SOCKET..net

    管道分爲有名管道和無名管道,無名管道只能用於親屬進程之間的通訊,而有名管道則可用於無親屬關係的進程之間。線程

    消息隊列用於運行於同一臺機器上的進程間通訊,與管道類似;

  共享內存一般由一個進程建立,其他進程對這塊內存區進行讀寫。獲得共享內存有兩種方式:映射/dev/mem設備和內存映像文件。前一種方式不給系統帶來額外的開銷,但在現實中並不經常使用,由於它控制存取的是實際的物理內存;

     本質上,信號量是一個計數器,它用來記錄對某個資源(如共享內存)的存取情況。通常說來,爲了得到共享資源,進程須要執行下列操做:

 

  (1)測試控制該資源的信號量;

 

  (2)若此信號量的值爲正,則容許進行使用該資源,進程將進號量減1;

 

  (3)若此信號量爲0,則該資源目前不可用,進程進入睡眠狀態,直至信號量值大於0,進程被喚醒,轉入步驟(1);

 

  (4)當進程再也不使用一個信號量控制的資源時,信號量值加1,若是此時有進程正在睡眠等待此信號量,則喚醒此進程。
    套接字通訊並不爲Linux所專有,在全部提供了TCP/IP協議棧的操做系統中幾乎都提供了socket,而全部這樣操做系統,對套接字的編程方法幾乎是徹底同樣的

 

3、進程/線程同步機制與進程間通訊機制比較

很明顯2者有相似,可是差異很大

同步主要是臨界區、互斥、信號量、事件

進程間通訊是管道、內存共享、消息隊列、信號量、socket

共通之處是,信號量和消息(事件)

 

其餘資料:

進程間通信(IPC)方法主要有如下幾種:   
    管道/FIFO/共享內存/消息隊列/信號   

1.管道中還有命名管道和非命名管道(即匿名管道)之分,非命名管道(即匿名管道)只能用於父子進程通信,命名管道可用於非父子進程,命名管道就是FIFO,管道是先進先出的通信方式    

2.消息隊列是用於兩個進程之間的通信,首先在一個進程中建立一個消息隊列,而後再往消息隊列中寫數據,而另外一個進程則從那個消息隊列中取數據。須要注意的是,消息隊列是用建立文件的方式創建的,若是一個進程向某個消息隊列中寫入了數據以後,另外一個進程並無取出數據,即便向消息隊列中寫數據的進程已經結束,保存在消息隊列中的數據並無消失,也就是說下次再從這個消息隊列讀數據的時候,就是上次的數據!!!!    

3.信號量,它與WINDOWS下的信號量是同樣的,因此就不用多說了    

4.共享內存,相似於WINDOWS下的DLL中的共享變量,但LINUX下的共享內存區不須要像DLL這樣的東西,只要首先建立一個共享內存區,其它進程按照必定的步驟就能訪問到這個共享內存區中的數據,固然可讀可寫      

以上幾種方式的比較:    

1.管道:速度慢,容量有限,只有父子進程能通信    

2.FIFO:任何進程間都能通信,但速度慢    

3.消息隊列:容量受到系統限制,且要注意第一次讀的時候,要考慮上一次沒有讀完數據的問題    

4.信號量:不能傳遞複雜消息,只能用來同步    

5.共享內存區:可以很容易控制容量,速度快,但要保持同步,好比一個進程在寫的時候,另外一個進程要注意讀寫的問題,至關於線程中的線程安全,固然,共享內存區一樣能夠用做線程間通信,不過沒這個必要,線程間原本就已經共享了同一進程內的一塊內存

相關文章
相關標籤/搜索