進程、線程通信與同步

1.0 Linux進程間通訊

  1. 管道/FIFO:管道中還有命名管道和非命名管道(即匿名管道)之分,非命名管道(即匿名管道)只能用於父子進程通訊,命名管道可用於非父子進程,命名管道就是FIFO,管道是先進先出的通訊方式    
  2. 消息隊列:消息隊列是用於兩個進程之間的通訊,首先在一個進程中創建一個消息隊列,然後再往消息隊列中寫數據,而另一個進程則從那個消息隊列中取數據. 需要注意的是,消息隊列是用創建文件的方式建立的,如果一個進程向某個消息隊列中寫入了數據之後,另一個進程並沒有取出數據,即使向消息隊列中寫數據的進程已經結束,保存在消息隊列中的數據並沒有消失,也就是說下次再從這個消息隊列讀數據的時候,就是上次的數據!!!!    
  3. 信號量:信號量,它與WINDOWS下的信號量是一樣的,所以就不用多說了    
  4. 共享內存:共享內存,類似於WINDOWS下的DLL中的共享變量,但LINUX下的共享內存區不需要像DLL這樣的東西,只要首先創建一個共享內存區,其它進程按照一定的步驟就能訪問到這個共享內存區中的數據,當然可讀可寫   
  5. 信號:signal
  6. 套接字socket

IPC比較

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

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

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

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

5.共享內存:能夠很容易控制容量,速度快,但要保持同步,比如一個進程在寫的時候,另一個進程要注意讀寫的問題,相當於線程中的線程安全(全局變量和靜態變量引起),當然,共享內存區同樣可以用作線程間通訊,不過沒這個必要,線程間本來就已經共享了同一進程內的一塊內存

2.0 線程同步方法

  • 臨界區:通過對多線程串行化來訪問公共資源或一段代碼,速度快,適合控制數據訪問
  • 互斥量:爲協調共同對一個共享資源的單獨訪問而設計的.
  • 信號量:爲控制一個具有有限數量用戶資源而設計.
  • 事件對象:用來通知線程有一些事件已發生,從而啓動後繼任務的開始.

1、  事件對象(Event)

用事件(Event)來同步線程是最具彈性的了. 一個事件有兩種狀態:激發狀態和未激發狀態. 也稱有信號狀態和無信號狀態. 事件又分兩種類型:手動重置事件和自動重置事件. 手動重置事件被設置爲激發狀態後,會喚醒所有等待的線程,而且一直保持爲激發狀態,直到程序重新把它設置爲未激發狀態. 自動重置事件被設置爲激發狀態後,會喚醒“一個”等待中的線程,然後自動恢復爲未激發狀態. 所以用自動重置事件來同步兩個線程比較理想.

2、  臨界區(CriticalSection)
使用臨界區域的第一個忠告就是不要長時間鎖住一份資源. 但進入臨界區後必須儘快地離開,釋放資源. 如果不釋放的話,會如何?答案是不會怎樣. 臨界區域的一個缺點就是:CriticalSection不是一個核心對象,無法獲知進入臨界區的線程是生是死,如果進入臨界區的線程掛了,沒有釋放臨界資源,系統無法獲知,而且沒有辦法釋放該臨界資源. 這個缺點在互斥器(Mutex)中得到了彌補.

3、  互斥量(Mutex)
互斥器的功能和臨界區域很相似. 區別是:Mutex所花費的時間比CriticalSection多的多,但是Mutex是核心對象(Event、Semaphore也是),可以跨進程使用,而且等待一個被鎖住的Mutex可以設定TIMEOUT,不會像CriticalSection那樣無法得知臨界區域的情況,而一直死等.

4、 信號量(Semaphore)
信號量是最具歷史的同步機制. 信號量是解決producer/consumer問題的關鍵要素.

3.0線程通信

1.全局變量

進程中的線程間內存共享,這是比較常用的通信方式和交互方式.

注:定義全局變量時最好使用volatile來定義,以防編譯器對此變量進行優化. 

2.Message消息機制

常用的Message通信的接口主要有兩個:PostMessage和PostThreadMessage,

PostMessage爲線程向主窗口發送消息. 而PostThreadMessage是任意兩個線程之間的通信接口.

3.事件對象(CEvent對象)

4.0同步與互斥比較

  • 所謂同步,是指散步在不同進程之間的若干程序片斷,它們的運行必須嚴格按照規定的某種先後次序來運行,這種先後次序依賴於要完成的特定的任務.
  • 所謂互斥,是指散佈在不同進程之間的若干程序片斷,當某個進程運行其中一個程序片段時,其它進程就不能運行它們之中的任一程序片段,只能等到該進程運行完這個程序片段後纔可以運行

5.0 死鎖

產生死鎖的原因

(1)競爭資源
(2)進程推進順序不當

產生死鎖的必要條件

(1)互斥條件:一個資源在一段時間內只能被一個進程所使用,具有排它性. 
(2)請求和保持:一個進程在請求新資源而阻塞時,對已獲得資源又保持不放. 
(3)不剝奪:進程已獲得的資源,在未使用完之前不能被剝奪,只能在使用完時由自己釋放.

(4)環路等待:在發生死鎖時,必然存在一個進程--資源的環形鏈. 即進程集合{P1,P2,...,Pn}中的P1正在等待P2佔用的資源,P2正在等待P3佔用的資源,...,Pn正在等待P1佔用的資源. 

 轉自:http://www.cnblogs.com/fora/archive/2011/05/06/2039511.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章