進程/線程同步、互斥、通信的問題:

最近也是遇到很多進程、線程同步、互斥,進程間通信的問題,這些問題放在一起很容易引起混淆,最近也查閱了相關的書籍資料和一些博客,在此寫出自己的一些相關總結,希望對大家有幫助。

首先要說的是進程、線程兩種最基本的關係:競爭關係和協作關係
進程的互斥、同步、通信都是基於這兩種基本關係而存在的:
1.爲了解決進程間競爭關係(間接制約關係)而引入進程互斥;
2.爲了解決進程間鬆散的協作關係( 直接制約關係)而引入進程同步;
3.爲了解決進程間緊密的協作關係而引入進程通信

定義(以進程爲例):
進程互斥:指若干個進程要使用同一共享資源時,任何時刻最多允許一個進程去使用,其他要使用該資源的進程必須等待,直到佔有資源的進程釋放該資源。
進程的同步:是解決進程間協作關係( 直接制約關係) 的手段。進程同步指兩個以上進程基於某個條件來協調它們的活動。一個進程的執行依賴於另一個協作進程的消息或信號,當一個進程沒有得到來自於另一個進程的消息或信號時則需等待,直到消息或信號到達才被喚醒
進程通信:進程之間互相交換信息的工作稱之爲進程通信IPC (InterProcess Communication),多個進程之間相互通信,交換信息傳遞數據的方法

接下來分別說一下各部分:


進程同步:
不同的操作系統下進程同步的方式不同:
Linux 下:
Linux 下常見的進程同步方法有:SysVIPC 的 sem(信號量)、file locking / record locking(通過 fcntl 設定的文件鎖、記錄鎖)、futex(基於共享內存的快速用戶態互斥鎖)。針對線程(pthread)的還有 pthread_mutex 和 pthread_cond(條件變量)。

Windows下:
在Windwos中,進程同步主要有以下幾種:互斥量、信號量、事件、可等計時器等幾種技術。

在Windows下,進程通信主要有以下幾種:內存映射、管道、消息等,但是內存映射是最基礎的,因爲,其他的進程通信手段在內部都是考內存映射來完成的


以上所說的是進程的同步方式,接下來介紹線程常見的同步方式,這也是進程常見的同步方式:

線程間的同步方式:常見的同步機制主要是:臨界區、互斥區、事件、信號量這四種

臨界區:
臨界區對應着一個CcriticalSection對象,當線程需要訪問保護數據時,調用EnterCriticalSection函數;當對保護數據的操作完成之後,調用LeaveCriticalSection函數釋放對臨界區對象的擁有權,以使另一個線程可以奪取臨界區對象並訪問受保護的數據。
PS:關鍵段對象會記錄擁有該對象的線程句柄即其具有“線程所有權”概念,即進入代碼段的線程在leave之前,可以重複進入關鍵代碼區域。所以關鍵段可以用於線程間的互斥,但不可以用於同步(同步需要在一個線程進入,在另一個線程leave)

互斥量:
互斥與臨界區很相似,但是使用時相對複雜一些(互斥量爲內核對象),不僅可以在同一應用程序的線程間實現同步,還可以在不同的進程間實現同步,從而實現資源的安全共享。

信號量:
信號量的用法和互斥的用法很相似,不同的是它可以同一時刻允許多個線程訪問同一個資源,PV操作

事件:
事件分爲手動置位事件和自動置位事件。事件Event內部它包含一個使用計數(所有內核對象都有),一個布爾值表示是手動置位事件還是自動置位事件,另一個布爾值用來表示事件有無觸發。由SetEvent()來觸發,由ResetEvent()來設成未觸發。

注:信號量是進程同步與互斥的常用方法,也可以作爲低級的進程通信方法

接下來說一下進程間的通信方式:

進程同信:
根據進程通信時信息量大小的不同,可以將進程通信劃分爲兩大類型:
1、低級通信,控制信息的通信(主要用於進程之間的同步,互斥,終止和掛起等等控制信息的傳遞)
2、高級通信,大批數據信息的通信(主要用於進程間數據塊數據的交換和共享,常見的高級通信有管道,消息隊列,共享內存等).

進程通信的具體方式:
1.管道( pipe ):管道是一種半雙工的通信方式,數據只能單向流動,提供的共享文件通信機制
2.有名管道 (named pipe) : 有名管道也是半雙工的通信方式
3.信號量( semophore ) : 信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。不是用於交換大批數據,而用於多線程之間的同 步.常作爲一種鎖機制,防止某進程在訪問資源時其它進程也訪問該資源。
4.消息隊列( message queue ) : 消息隊列是由消息的鏈表,存放在內核中並由消息隊列標識符標識。
5.信號 ( signal ) : 信號是一種比較複雜的通信方式,用於通知接收進程某個事件已經發生。
6.共享內存( shared memory ):共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。
7.套接字( socket ) : 套解口也是一種進程間通信機制,與其他通信機制不同的是,它可用於不同機器間的進程通信。

注:管道與管程是不同的,管程是進程同步的方式,而管道則是進程通信的方式

這裏再簡單介紹一下線程通信的三種方式:
線程間通信:
1.使用全局變量
主要由於多個線程可能更改全局變量,因此全局變量最好聲明爲violate
2.使用消息實現通信
在Windows程序設計中,每一個線程都可以擁有自己的消息隊列(UI線程默認自帶消息隊列和消息循環,工作線程需要手動實現消息循環),因此可以採用消息進行線程間通信
3.使用事件CEvent類實現線程間通信
Event對象有兩種狀態:有信號和無信號,線程可以監視處於有信號狀態的事件,以便在適當的時候執行對事件的操作。


綜上所述:進程互斥、同步與通信的關係:互斥是一種特殊的同步,進程同步是一種進程通信,由此看來,進程互斥、同步都可以看做進程的通信

希望大家有什麼自己的看法可以留言一起進行討論,謝謝

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