進程間通訊方式總結

前言

進程間的通訊方式,其實咱們一直在用它,可是咱們都不會去注意它。若是碰到面試官問你知道多少種進程間的通訊方式,估計不少人都會有點懵。今天咱們就來總結下進程間的通訊方式有哪些。java

管道

管道,英文爲pipe。這是一個咱們在學習Linux命令行的時候就會引入的一個很重要的概念。它的發明人是道格拉斯.麥克羅伊,這位也是UNIX上早期shell的發明人。他在發明了shell以後,發現系統操做執行命令的時候,常常有需求要將一個程序的輸出交給另外一個程序進行處理,也所以,管道應運而生了。面試

管道能夠分爲兩類:匿名管道和命名管道。shell

常見的Linux命令 "|" 其實就是匿名管道,表示把一個進程的輸出傳輸到另一個進程,如:安全

echo "Happyjava" | awk -F 'j' '{print $2}'
# 輸出 ava
複製代碼

另外,咱們能夠經過 mkfifo <pipename> 命令建立一個命名管道,如:bash

mkfifo pipe
複製代碼

一個進程往管道輸入數據,則會阻塞等待別的進程從管道讀取數據:服務器

若是我另一個窗口沒有執行 cat < pipe 命令,則左邊的窗口(echo 'Happyjava' > pipe)會一直阻塞。微信

消息隊列

注意,此消息隊列不是咱們經常使用的MQ,如kafka,rabbitmq,rocketmq等。數據結構

消息隊列提供了一種從一個進程向另外一個進程發送一個數據塊的方法。 每一個數據塊都被認爲含有一個類型,接收進程能夠獨立地接收含有不一樣類型的數據結構。咱們能夠經過發送消息來避免命名管道的同步和阻塞問題。可是消息隊列與命名管道同樣,每一個數據塊都有一個最大長度的限制。app

使用消息隊列進行進程間通訊,可能會收到數據塊最大長度的限制約束等,這也是這種通訊方式的缺點。若是頻繁的發生進程間的通訊行爲,那麼進程須要頻繁地讀取隊列中的數據到內存,至關於間接地從一個進程拷貝到另外一個進程,這須要花費時間。學習

共享內存

共享內存這個通訊方式就能夠很好着解決拷貝所消耗的時間了。系統加載一個進程的時候,分配給進程的內存並非實際物理內存,而是虛擬內存空間。那麼咱們可讓兩個進程各自拿出一塊虛擬地址空間來,而後映射到相同的物理內存中,這樣,兩個進程雖然有着獨立的虛擬內存空間,但有一部分倒是映射到相同的物理內存,這就完成了內存共享機制了。

信號量

共享內存最大的問題是什麼?沒錯,就是多進程競爭內存的問題,就像相似於咱們平時說的線程安全問題。如何解決這個問題?這個時候咱們的信號量就上場了。

信號量的本質就是一個計數器,用來實現進程之間的互斥與同步。例如信號量的初始值是 1,而後 a 進程來訪問內存1的時候,咱們就把信號量的值設爲 0,而後進程b 也要來訪問內存1的時候,看到信號量的值爲 0 就知道已經有進程在訪問內存1了,這個時候進程 b 就會訪問不了內存1。因此說,信號量也是進程之間的一種通訊方式。

Socket

這個就是咱們一直在用的進程間的通訊方式了,如咱們的微信APP跟微信服務器通訊,其實就是使用的Socket套接字進行通訊的。

總結

這裏總結下,進程(Linux)間的通訊方式有:

一、管道

二、消息隊列

三、共享內存

四、信號量

五、Socket

相關文章
相關標籤/搜索