程序之間的通訊方式有管道、訊息佇列、共享記憶體、訊號量和socket五種方式。
管道
來看一條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程序才能返回(同步阻塞)。因此管道不適合頻繁通訊的程序。
管道的優點則是比較簡單,而且能夠保證我們的資料已經真的被其他程序拿走了。
訊息佇列
知道了管道這種通訊方式的缺點之後,有的人就想了,能不能把程序的資料放在某個記憶體之後就馬上讓程序返回,而無需等待其他程序來取呢?
答案是可以的,有人想出了訊息佇列的通訊方式來解決這個問題。比如a程序要給b程序傳送訊息,只需要把訊息放在對應的訊息佇列裡面就可以了,b程序需要的時候再去對應的訊息佇列裡面取出來。同理,b程序要給a程序傳送訊息也是一樣的。
訊息佇列這種通訊方式同樣類似於快取,存在讀寫大快取效能可能很差的缺點。如果a程序傳送的資料佔的記憶體比較大,並且程序之間的通訊特別頻繁的話,傳送訊息(拷貝)這個過程可能就需要花很多的時間來讀記憶體中的資料。
共享記憶體
共享記憶體這個通訊方式就很好地解決了拷貝資料消耗的時間。
通常來講,每個程序是有自己的獨立記憶體的,共享記憶體則是通過特定的機制實現的。我們都知道,系統在載入乙個程序的時候,分配給程序的記憶體並不是實際的物理記憶體,而是虛擬的記憶體空間。我們可以讓兩個程序各自拿出一塊虛擬位址空間來,然後對映到相同的物理記憶體中,這樣兩個程序雖然有著獨立的虛擬記憶體空間,卻會有一部分是對映到相同的物理記憶體,也就實現了記憶體共享。
訊號量(共享記憶體的高階)
共享記憶體最大的問題就是多程序競爭記憶體的問題,也就是執行緒安全的問題。解決這個問題的方法就是訊號量。
訊號量的本質是乙個計數器,用來實現程序之間的互斥與同步。例如訊號量的初始值是1,當程序a訪問記憶體1的時候,我們會把訊號量的值設為0,然後當程序b也要訪問記憶體1的時候,看到訊號量的值為0就知道已經有程序在訪問記憶體1了,這個時候程序b就訪問不了記憶體1了,相當於鎖的機制。
因為程序之間讀取共享記憶體之前要先讀取訊號量,因此訊號量也可以看作是程序之間的一種通訊方式。
socket
上面所說的管道、訊息佇列、共享記憶體和訊號量都是多個程序在一台主機之間的通訊,而不同主機之間的程序則是通過socket進行通訊的。比如通過瀏覽器發起的http請求和伺服器返回的響應就是通過socket的通訊方式實現的。
總結
了解程序之間的通訊方式是十分必要的,比如jvm就是用得共享記憶體的方式,對於幫助了解jvm的底層機制起了重要作用。
"你的晚安,是下意識的惻隱。"
程序之間的通訊方式
1 管道 pipe 管道可用於具有親緣關係程序間的通訊,允許乙個程序和另乙個與它有共同祖先的程序之間進行通訊。2 命名管道 name pipe 命名管道克服了沒有名字的限制,因此,除了具有管道所擁有的功能外,它還允許無親緣關係程序間同通訊。命名管道在檔案系統中有對應的檔名。命名管道通過命令mkfif...
程序之間的通訊方式
資料傳輸 資源共享 通知事件 程序控制 是管道的意思,它的作用就是把前一條命令的輸出作為後一條命令的輸入。如果兩個程序要通訊的話,可以使用這種管道進行通訊,因為 沒有名字,所以成為匿名管道,匿名管道一般用於有父子程序關係的程序中 並且這種通訊方式是單向的,只能把第乙個命令的輸出作為第二個命令的輸入,...
程序之間 執行緒之間的通訊方式
1 程序間的8中通訊方式 1 無名管道 pipe 管道是一種半雙工的通訊方式,資料只能單向流動,而且只能在具有親緣關係的程序間使用。程序的親緣關係通常是指父子程序關係。2 2 高階管道 popen 將另乙個程式當做乙個新的程序在當前程式程序中啟動,則它算是當前程式的子程序,這種方式我們成為高階管道方...