行程間為什么需要資料通信?
- 資料傳輸:一個行程需要將它的資料傳送給另外一個行程,
- 資源共享:多個行程之間共享相同的資源,
- 通知事件:一個行程需要向另外一組行程發送訊息,通知它們發生了某種事件,
- 行程控制:有些行程需要完全控制另一個行程的執行,該控制行程希望能夠攔截另外一個行程的所有操作,并且能夠及時知道它的狀態改變,
主要有管道、訊息佇列、共享記憶體、信號量、信號、Socket等六種方式,
管道
管道的本質是內核中的一個快取,當記憶體創建一個管道后,Linux會回傳兩個檔案描述符號,一個是寫入端的描述符,一個是輸出端的描述符,可以通過這兩個描述符往管道里寫入或者讀取資料,如果想要實作兩個行程通過管道來通信,則需要讓創建管道的行程fork子行程,這樣子行程就擁有了父行程的檔案描述符,這樣子行程之間可以對同一管道的操作,管道這種行程通信方式雖然使用簡單,但是效率比較低,不適合行程間頻繁地交換資料,并且管道只能傳輸無格式的位元組流,
訊息佇列
訊息佇列的本質就是存放在記憶體中的訊息鏈表,而訊息本質上是用戶自定義的資料結構,如果行程在訊息佇列種讀取了某個訊息,這個訊息就會被從訊息佇列種洗掉,
- 訊息佇列允許一個或者多個行程向他寫入或者讀取資料,
- 訊息佇列可以不遵循FIFO,進行訊息隨機查詢,
- 訊息佇列的生命周期與內核相同,
- 訊息佇列對于交換較少數量的資料很有用,因為無需避免沖突,因為用戶行程往訊息佇列種讀寫資料,需要進行系統呼叫,如果資料量大會造成頻繁的系統呼叫,因此需要更多的時間以便于內核介入,
共享記憶體
共享記憶體就是允許不相干的行程將同一段物理記憶體連接到它們各自的地址空間中,使得這些記憶體可以訪問同一個物理空間,這個物理記憶體就成為共享記憶體,
- 兩個不同行程的邏輯地址通過頁表映射到物理空間的同一區域,它們所共同指向的這塊區域就是共享記憶體,
- 訊息佇列無需避免沖突,而共享記憶體機制可能會發生沖突,
信號量
在多道批處理系統中,多個行程是可以并發執行的,但由于系統的資源有限,行程的執行不是一貫到底的, 而是走走停停,以不可預知的速度向前推進(異步性),但有時候我們又希望多個行程能密切合作,按照某個特定的順序依次執行,以實作一個共同的任務,
為了解決上述這兩個問題,保證共享記憶體在任何時刻只有一個行程在訪問(互斥),并且使得行程們能夠按照某個特定順序訪問共享記憶體(同步),我們就可以使用行程的同步與互斥機制,常見的比如信號量與 PV 操作,行程的同步與互斥其實是一種對行程通信的保護機制,并不是用來傳輸行程之間真正通信的內容的,但是由于它們會傳輸信號量,所以也被納入行程通信的范疇,稱為低級通信,
- 信號量:信號量其實就是一個變數 ,我們可以用一個信號量來表示系統中某種資源的數量,例如系統連接的列印機資源的數量,可以設定一個初值為1的信號量,
- 原語:作業系統提供的一對原語來對信號量進行操作,
- P操作:
信號量--,表示申請占用一個資源,如果申請結果小于0,則無資源可用,P操作的行程被阻塞, - V操作:
信號量++,表示釋放一個資源,如果信號量+1<0,表明有行程處于阻塞中等待資源,因此可以喚醒一個等待中的行程,使其運行下去, - 可以這么理解,當信號量的值為 2 的時候,表示有 2 個資源可以使用,當信號量的值為 -2 的時候,表示有兩個行程正在等待使用這個資源,
- P操作:
信號
通過發送指定信號來通知某個異步事件的發送,以迫使行程進行信號處理程式,信號處理完畢后,被中斷的行程將恢復執行,
- 信號和信號量是完全不同的概念,
- 信號是行程通信機制中唯一的異步通信機制,它可以在任何時候發送信號給某個行程,
- 信號事件的來源主要有硬體來源和軟體來源,
- 硬體來源,例如組合鍵Ctrl+C 產生 SIGINT 信號,表示終止該行程,
- 軟體來源,通過 kill 系列的命令給行程發送信號,比如 kill -9 1111,給PID 1111行程發送SIGKILL信號,
Socket
通過Socket相關協議,一臺計算機可以接收其他計算機的資料,也可以向其他計算機發送資料,當然也能完成同主機上的行程通信,
- Socket本質上是一個API,是應用層與TCP/IP協議的中間軟體抽象層,對TCP/IP進行了封裝,
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/546404.html
標籤:其他
