天天看點

程序之間究竟有哪些通信方式

有一次面試的時候,被問到程序之間有哪些通信方式,不過由于之前沒深入思考且整理過,說的并不好。想必大家也都知道程序有哪些通信方式,可是我猜很多人都是靠着”背“來記憶的,是以今天的這篇文章,講給大家詳細着講解他們是如何通信的,讓大家盡量能夠了解他們之間的差別、優缺點等,這樣的話,以後面試官讓你舉例子,你也能夠順手拈來。

1、管道

我們來看一條 Linux 的語句

 netstat -tulnp | grep 8080           

學過 Linux 命名的估計都懂這條語句的含義,其中”|“是管道的意思,它的作用就是把前一條指令的輸出作為後一條指令的輸入。在這裡就是把 netstat -tulnp 的輸出結果作為 grep 8080 這條指令的輸入。如果兩個程序要進行通信的話,就可以用這種管道來進行通信了,并且我們可以知道這條豎線是沒有名字的,是以我們把這種通信方式稱之為匿名管道。

并且這種通信方式是單向的,隻能把第一個指令的輸出作為第二個指令的輸入,如果程序之間想要互相通信的話,那麼需要建立兩個管道。

居然有匿名管道,那也意味着有命名管道,下面我們來建立一個命名管道。

 mkfifo  test           

這條指令建立了一個名字為 test 的命名管道。

接下來我們用一個程序向這個管道裡面寫資料,然後有另外一個程序把裡面的資料讀出來。

 echo "this is a pipe" > test   // 寫資料           

這個時候管道的内容沒有被讀出的話,那麼這個指令就會一直停在這裡,隻有當另外一個程序把 test 裡面的内容讀出來的時候這條指令才會結束。接下來我們用另外一個程序來讀取

 cat < test  // 讀資料           

我們可以看到,test 裡面的資料被讀取出來了。上一條指令也執行結束了。

從上面的例子可以看出,管道的通知機制類似于緩存,就像一個程序把資料放在某個緩存區域,然後等着另外一個程序去拿,并且是管道是單向傳輸的。

這種通信方式有什麼缺點呢?顯然,這種通信方式效率低下,你看,a 程序給 b 程序傳輸資料,隻能等待 b 程序取了資料之後 a 程序才能傳回。

是以管道不适合頻繁通信的程序。當然,他也有它的優點,例如比較簡單,能夠保證我們的資料已經真的被其他程序拿走了。我們平時用 Linux 的時候,也算是經常用。

2、消息隊列

那我們能不能把程序的資料放在某個記憶體之後就馬上讓程序傳回呢?無需等待其他程序來取就傳回呢?

答是可以的,我們可以用消息隊列的通信模式來解決這個問題,例如 a 程序要給 b 程序發送消息,隻需要把消息放在對應的消息隊列裡就行了,b 程序需要的時候再去對應的

消息隊列裡取出來。同理,b 程序要個 a 程序發送消息也是一樣。這種通信方式也類似于緩存吧。

這種通信方式有缺點嗎?答是有的,如果 a 程序發送的資料占的記憶體比較大,并且兩個程序之間的通信特别頻繁的話,消息隊列模型就不大适合了。因為 a 發送的資料很大的話,意味發送消息(拷貝)這個過程需要花很多時間來讀記憶體。

哪有沒有什麼解決方案呢?答是有的,請繼續往下看。

3、共享記憶體

共享記憶體這個通信方式就可以很好着解決拷貝所消耗的時間了。

這個可能有人會問了,每個程序不是有自己的獨立記憶體嗎?兩個程序怎麼就可以共享一塊記憶體了?

我們都知道,系統加載一個程序的時候,配置設定給程序的記憶體并不是實際實體記憶體,而是虛拟記憶體空間。那麼我們可以讓兩個程序各自拿出一塊虛拟位址空間來,然後映射到相同的實體記憶體中,這樣,兩個程序雖然有着獨立的虛拟記憶體空間,但有一部分卻是映射到相同的實體記憶體,這就完成了記憶體共享機制了。

4、信号量

共享記憶體最大的問題是什麼?沒錯,就是多程序競争記憶體的問題,就像類似于我們平時說的線程安全問題。如何解決這個問題?這個時候我們的信号量就上場了。

信号量的本質就是一個計數器,用來實作程序之間的互斥與同步。例如信号量的初始值是 1,然後 a 程序來通路記憶體1的時候,我們就把信号量的值設為 0,然後程序b 也要來通路記憶體1的時候,看到信号量的值為 0 就知道已經有程序在通路記憶體1了,這個時候程序 b 就會通路不了記憶體1。是以說,信号量也是程序之間的一種通信方式。

5、Socket

上面我們說的共享記憶體、管道、信号量、消息隊列,他們都是多個程序在一台主機之間的通信,那兩個相隔幾千裡的程序能夠進行通信嗎?

答是必須的,這個時候 Socket 這家夥就派上用場了,例如我們平時通過浏覽器發起一個 http 請求,然後伺服器給你傳回對應的資料,這種就是采用 Socket 的通信方式了。

總結

是以,程序之間的通信方式有:

講到這裡也就完結了,之前我看程序之間的通信方式的時候,也算是死記硬背,并沒有去了解他們之間的關系,優缺點,為什麼會有這種通信方式。是以最近花點時間去研究了一下,