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