轉:——Windows和Linux進程間通信區別

http://blog.sina.com.cn/s/blog_7bbb91b70100uui2.html    

      進程間通信

多進程和多線程本質上就是將原來一個進程或者線程處理的任務分給了多個進程或者線程,也可以說是將原來一個CPU處理的任務分給了多個CPU處理,類似於隨着生產力的發展,原來一個人包打天下的個人英雄主義時代被分工合作的團隊取代一樣。

既然是一個團隊,就必然涉及到分工合作問題,並行程序的設計本質上就是解決“分工”和“合作”的問題。其中“分工”主要是後面講到“並行程序設計模式”,而“合作”則是本篇重點要討論的問題。

相信大家做過項目的都知道所謂合作其實就是“通信”和“衝突解決”。常見的“通信”有開會、電話、郵件、甚至QQ等,無非是爲了交換信息,而“衝突解決”其實就是爲了解決資源不足,大家搶着用的問題。

可能許多菜鳥、大俠以及網上的很多博客都和和我開始一樣,將“通信”和“衝突解決”混爲一談了,一說到進程間通信,就會口若懸河的冒出一大堆名詞:管道、信號量、消息隊列、互斥。。。。。這裏面有的是“通信”(管道、消息隊列),有的是“衝突解決”(信號量、互斥),並不是一類東東。

下面我們分別從“通信”和“衝突解決”兩方面來比較WindowsLinux

1.1        Windows進程間通信

標準(例如《Windows系統編程》裏面提到的)的Windows進程間通信有三個:匿名管道、命名管道(又叫FIFO)、郵槽(MailSlot),實際上常用的還有一個:共享內存。之所以說它不是標準的,我猜測可能是共享內存設計本意不是爲了進程間通信用的,而是爲了內存映射用的。

1.1.1   匿名管道

顧名思義:匿名管道就是“匿名”的“管道”。爲什麼這樣拆開呢?正所謂名如其人,通過名字我們就可以瞭解大概這是個什麼東東。

匿名:之所以叫做“匿名”,當然是因爲沒有名字了,但爲什麼會沒有名字呢?沒有名字又有什麼好處呢?其實很簡單了,“匿名”當然是不想讓其它人知道了,說白了這個“匿名管道”就是隻給父子進程用的,別人不需要也不可能知道名字的。

管道:說道管道,你是否想到了“下水管道”、“煤氣管道”等?對了,和這些管道本質上是一樣的,就是可以傳送東西的,所以叫做管道。要注意匿名管道是“單向流通”(也叫半雙工)的。

1.1.2   命名管道

聰明的你看到這個名字肯定就會產生如下兩個想法,我們就一一來解答:

1)和匿名管道看起來很像

是的,命名管道就是相對匿名管道來說的。

2)命名管道和匿名管道有什麼差別?

對比點

匿名管道

命名管道

備註

消息格式

字符

二進制

命名管道可以控制讀消息的長度

工作模式

半雙工

全雙工

NA

訪問模式

只能在一臺機器上

可以跨網絡

NA

通信模式

一對一,父子進程用

一對多,不同的進程都可以用

一個命名管道可以有多個實例

 

1.1.3   郵槽

郵槽和命名管道類似,都是有名字的,也可以跨網絡進行通信,既然是這樣,爲什麼Windows還要設計郵槽呢?其實也沒有什麼玄虛,說簡單點就是管道都是“點對點”的(命名管道雖然是一對多,但具體的通信還是11進行的),而郵槽是爲了提供一種“廣播”通信機制(王婆賣瓜一下:微軟還不如將郵槽叫做“廣播”:-P)。

下面我們看看郵槽和命名管道的對比:

對比點

郵槽

命名管道

備註

消息格式

數據包

二進制

命名管道可以控制讀消息的長度

工作模式

單向

全雙工

廣播當然是單向的了

訪問模式

可以跨網絡

可以跨網絡

NA

 

1.1.4   共享內存

就像前面提到的一樣,共享內存並不是正統的進程間通信的機制,共享內存其實只不過是Windows“內存映射文件”的一個特殊用法而已。

然而實際中共享內存在進程間通信卻比較常見,從使用方便性上來說,共享內存其實沒有前面介紹的方便(必須結合互斥、事件等一起使用),但爲什麼應用比較多呢?關鍵在於共享內存性能很高

共享內存應該是介於匿名管道和命名管道之間的通信方式,爲什麼這麼說呢?主要有如下幾個原因:

1)共享內存和匿名管道相比:共享內存有名稱,可用於多個進程通信,這點像命名管道;

2)共享內存和命名管道相比:共享內存只能在一臺機器上使用,不能跨網絡,這點和匿名管道類似

3)共享內存是雙向的,這點又和命名管道類似。

 

1.2        Linux進程間通信

介紹完了Windows,介紹Linux就相對輕鬆一些了,雖然WindowsLinux形同水火,打的不可開交,但實際上說白了,它們並不是兩個完全不同的東東,在很多的地方都相似,進程間通信也不例外。

Linux的進程間通信主要有管道、命名管道、消息隊列、共享內存、信號量,其中信號量Semaphore其實是爲了同步用的,因此我這裏就放到下一篇關於同步的博文中去分析。另外,很多人將信號signal也作爲進程間通信,但我認爲信號更像是爲了同步而設計的,因此也放到下一篇博文中去分析。

1.2.1   管道

Linux的管道和Windows的管道是一樣的,這裏就不詳細介紹了。

需要注意的是Linux多了一個叫做“流管道”的東東,除了流管道是全雙工(也就是雙向)外,流管道其它都和管道一樣。

1.2.2   命名管道

Linux的命名管道和Windows的命名管道差異就比較大了,主要對比如下:

對比點

Linux

Windows

備註

消息格式

字節流

二進制

Windows更牛

工作模式

半雙工

全雙工

Windows更牛

訪問模式

只能在一臺機器上

可以跨網絡

Windows更牛

 

1.2.3   消息隊列

這個是Linux特有的進程通信方式,我感覺它有點像郵槽,都能夠實現一對多。不過消息隊列和郵槽的方向正好相反:消息隊列是一堆進程向一個進程發,郵槽是一個進程向一堆進程發

消息隊列還有一個牛B的特性就是消息隊列的消息可以分優先級,進程不一定非要取第一個消息,也可以取指定消息優先級的消息。因此這個特性又可用於多對多通信,即:不同的收方指定不同的優先級。當然實際應用中應該沒人會這麼用,直接創建多個消息隊列是最方便、最簡單、效率最高的方法。

1.2.4   共享內存

Linux的共享內存機制和Windows本質上是一樣的,即都是利用了內存映射的功能。不過Linux將“內存映射到內存”包裝成了“共享內存”,而不像Windows,在使用的時候通過指定不同的參數來區分是“內存映射到文件”還是“共享內存”,所以各位大俠可能在網上有時能夠看到有人將“內存映射”和“共享內存”都說是Linux進程間通信的方式,原因就在這裏。

1.3        OS間進程通信

前面分別介紹了WindowsLinux進程間通信,看到這裏,你肯定會有疑問:什麼?還有OS進程間通信?不同OS之間的進程是不可能通信的!

是的,從操作系統層面來說,Windows的進程和Linux的進程當然是不能通信的,但如果從網絡層面來說,兩臺機器總是要通信的吧?不可能Windows只能和Windows通信,Linux只和Linux通信吧?

說到這裏估計你已經恍然大悟了:不就是Socket通信麼?

是的,就是它,雖然它是用於機器間通信的,但大家想想,機器間通信不就是各個應用程序通信麼?各個應用程序不就是對應操作系統中的一個或者多個進程麼?

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