深入理解進程間通信(IPC)



1、進程間通信主要有四種形式:管道(pipe)、消息隊列、信號量、共享內存。
2、首先說一下最基本的管道,管道分:命名管道和匿名管道;
3、匿名管道主要用在具有親緣關係的進程之間通信,調用pipe函數創建匿名管道,一端用於寫另一端用於讀,當進程之間在進行讀寫的時候會發生阻塞,即當寫端沒有再向管道里寫數據時,讀端讀完最後一個數據後就會阻塞,而且匿名管道是半雙工的,意思是在同一時刻只能進行單項通信,
4、由於匿名管道缺點所以就提出命名管道,命名管道的實現是創建一個實實在在存在的文件,然後不同的進程可以往裏寫數據也可以從裏讀數據,進程之間可以不具有親緣關係,創建命名管道的函數有兩個:mknode和mkfifo,但用得比較多的是mkfifo。
5、剛纔說的是最基本的進程間通信的管道,現在說一下system V 標準的消息隊列,消息隊列也打開了一個文件,一端用於寫一端用於讀,但是它和命名管道不同之處是命名管道是基於字節流,而消息隊列是基於數據報的傳輸,它們都有一個共同的缺點是傳輸的數據都有最大值的限制,消息隊列的實現主要有msgget(創建線性隊列)、msgsend(發送消息隊列)、msgrecv(接受消息隊列)、msgctl(設置消息隊列屬性)這四個函數來完成的。
6、第二個進程間通信是信號量:信號量其實本質就是一把數據鎖,它並沒事實實在在的傳輸數據,只是給傳輸的數據上鎖,然後讓它們安全可靠的輸出而已,它是實現主要靠:semget(創建信號量)、semop(主要爲了加鎖和解鎖)、semctl(設置信號量屬性),裏面主要有一個P、V操作,P操作:如果有資源,那麼資源數減一,給操作這塊資源的操作上鎖,V操作:如果有資源,資源數加一,等待被訪問。當請求不到資源是時候會阻塞式的等待。
7、第三個要說的進程間通信是共享內存:它是通過打開一個文件,讓所有的進程都共享這個文件,從而時間進程間通信。它其實會出現一個安全性問題,就是沒有同步機制,如果在多線程訪問的話就很可能出安全性問題,所以一般共享內存通常會和信號量搭配使用,它主要實現靠shmget(創建共享內存)、shmat(剛創建的共享內存還不能被所有進程訪問,必須調用shmat纔可以被進程訪問)、shmdt(讓訪問共享內存的進程分離)、shmctl(對共享內存的屬性進行設置),  既然共享內存有安全性問題爲什麼還有用它呢???因爲共享內存的通信很快,而且它的接口函數很簡單,只要加上同步機制在安全方面就沒問題了。

8、說到安全性問題,這裏說一下爲什麼不加鎖的話就不安全了,因爲當程序需要改變一個數的時候,它的操作是這樣的:先去內存裏讀數據到寄存器裏,然後從寄存器裏把數據取出來,修改後在先寫會寄存器,然後在寫會內存。試想一下,當對一個數進行加一的時候,因爲加一的操作不是原子性的,所以當把數據加一了後寫會寄存器時剛好進程或者線程被切換出去了,而切換出去的進程或線程剛好要用到以爲被加後的數據,其實沒加,所以最後得到是值不是預期的值。

9、以上這些就是我所掌握的進程間通信。










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