進程之間究竟有哪些通信⽅方式?如何通信? mkfifo - 創建FIFO(命名管道)

文章來自帥地玩編程
進程之間究竟有哪些通信⽅方式?如何通信?
1、管道
我們來看⼀一條 Linux 的語句句

netstat -tulnp | grep 8080

 學過 Linux 命名的估計都懂這條語句句的含義,其中”|“是管道的意思,它的作⽤用就是把前⼀一條命令的輸出

作爲後⼀一條命令的輸⼊入。在這⾥裏里就是把 netstat -tulnp 的輸出結果作爲 grep 8080 這條命令的輸⼊入。如
果兩個進程要進⾏行行通信的話,就可以⽤用這種管道來進⾏行行通信了了,並且我們可以知道這條豎線是沒有名字
的,所以我們把這種通信⽅方式稱之爲匿匿名管道。
並且這種通信⽅方式是單向的,只能把第⼀一個命令的輸出作爲第⼆二個命令的輸⼊入,如果進程之間想要互相
通信的話,那麼需要創建兩個管道。
居然有匿匿名管道,那也意味着有命名管道,下⾯面我們來創建⼀一個命名管道。

mkfifo - 創建FIFO(命名管道)

makefifo test

這條命令創建了了⼀一個名字爲 test 的命名管道。
接下來我們⽤用⼀一個進程向這個管道⾥裏里⾯面寫數據,然後有另外⼀一個進程把⾥裏里⾯面的數據讀出來。

 

echo "this is a pipe">test

 

這個時候管道的內容沒有被讀出的話,那麼這個命令就會⼀一直停在這⾥裏里,只有當另外⼀一個進程把 test ⾥裏里

⾯面的內容讀出來的時候這條命令纔會結束。接下來我們⽤用另外⼀一個進程來讀取

cat < test//讀數據

我們可以看到,test ⾥裏里⾯面的數據被讀取出來了了。上⼀一條命令也執⾏行行結束了了。
從上⾯面的例例⼦子可以看出,管道的通知機制類似於緩存,就像⼀一個進程把數據放在某個緩存區域,然後等
着另外⼀一個進程去拿,並且是管道是單向傳輸的。
這種通信⽅方式有什什麼缺點呢?顯然,這種通信⽅方式效率低下,你看,a 進程給 b 進程傳輸數據,只能等
待 b 進程取了了數據之後 a 進程才能返回。
所以管道不不適合頻繁通信的進程。當然,他也有它的優點,例例如⽐比較簡單,能夠保證我們的數據已經真
的被其他進程拿⾛走了了。我們平時⽤用 Linux 的時候,也算是經常⽤用。
2、消息隊列列
那我們能不不能把進程的數據放在某個內存之後就⻢馬上讓進程返回呢?⽆無需等待其他進程來取就返回呢?
答是可以的,我們可以⽤用消息隊列列的通信模式來解決這個問題,例例如 a 進程要給 b 進程發送消息,只需
要把消息放在對應的消息隊列列⾥裏里就⾏行行了了,b 進程需要的時候再去對應的 消息隊列列⾥裏里取出來。同理理,b 進
程要個 a 進程發送消息也是⼀一樣。這種通信⽅方式也類似於緩存吧。
netstat -tulnp | grep 8080
mkfifo test
echo "this is a pipe" > test // 寫數據
cat < test // 讀數據
這種通信⽅方式有缺點嗎?答是有的,如果 a 進程發送的數據佔的內存⽐比較⼤大,並且兩個進程之間的通信
特別頻繁的話,消息隊列列模型就不不⼤大適合了了。因爲 a 發送的數據很⼤大的話,意味發送消息(拷⻉貝)這個
過程需要花很多時間來讀內存。
哪有沒有什什麼解決⽅方案呢?答是有的,請繼續往下看。
3、共享內存
共享內存這個通信⽅方式就可以很好着解決拷⻉貝所消耗的時間了了。
這個可能有⼈人會問了了,每個進程不不是有⾃自⼰己的獨⽴立內存嗎?兩個進程怎麼就可以共享⼀一塊內存了了?
我們都知道,系統加載⼀一個進程的時候,分配給進程的內存並不不是實際物理理內存,⽽而是虛擬內存空間。
那麼我們可以讓兩個進程各⾃自拿出⼀一塊虛擬地址空間來,然後映射到相同的物理理內存中,這樣,兩個進
程雖然有着獨⽴立的虛擬內存空間,但有⼀一部分卻是映射到相同的物理理內存,這就完成了了內存共享機制
了了。
4、信號量量
共享內存最⼤大的問題是什什麼?沒錯,就是多進程競爭內存的問題,就像類似於我們平時說的線程安全問
題。如何解決這個問題?這個時候我們的信號量量就上場了了。
信號量量的本質就是⼀一個計數器器,⽤用來實現進程之間的互斥與同步。例例如信號量量的初始值是 1,然後 a 進
程來訪問內存1的時候,我們就把信號量量的值設爲 0,然後進程b 也要來訪問內存1的時候,看到信號量量
的值爲 0 就知道已經有進程在訪問內存1了了,這個時候進程 b 就會訪問不不了了內存1。所以說,信號量量也是
進程之間的⼀一種通信⽅方式。
5、Socket
上⾯面我們說的共享內存、管道、信號量量、消息隊列列,他們都是多個進程在⼀一臺主機之間的通信,那兩個
相隔⼏幾千⾥裏里的進程能夠進⾏行行通信嗎?
答是必須的,這個時候 Socket 這傢伙就派上⽤用場了了,例例如我們平時通過瀏覽器器發起⼀一個 http 請求,然
後服務器器給你返回對應的數據,這種就是採⽤用 Socket 的通信⽅方式了了。
總結
所以,進程之間的通信⽅方式有:
1、管道
2、消息隊列列
3、共享內存
4、信號量量
5、Socket

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