linux 管道 訊息佇列 共享記憶體的對比

2021-07-09 12:53:24 字數 1136 閱讀 4301

------管道

管道的優點是不需要加鎖,缺點是預設緩衝區太小,只有4k,同時只適合父子程序間通訊,而且乙個管道只適合單向通訊,如果要雙向通訊需要建立兩個。而且不適合多個子程序,因為訊息會亂,它的傳送接收機制是用read/write這種適用流的,缺點是資料本身沒有邊界,需要應用程式自己解釋,而一般訊息大多是乙個固定長的訊息頭,和乙個變長的訊息體,乙個子程序從管道read到訊息頭後,訊息體可能被別的子程序接收到

------訊息佇列

訊息佇列也不要加鎖,預設緩衝區和單訊息上限都要大一些,在我的suse10上是64k,它並不侷限於父子程序間通訊,只要乙個相同的key,就可以讓不同的程序定位到同乙個訊息佇列上,它也可以用來給雙向通訊,不過稍微加個標識,可以通過訊息中的type進行區分,比如乙個任務分派程序,建立了若干個執行子程序,不管是父程序傳送分派任務的訊息,還是子程序傳送任務執行的訊息,都將type設定為目標程序的pid,因為msgrcv可以指定只接收訊息型別為type的訊息,這樣就實現了子程序只接收自己的任務,父程序只接收任務結果

------共享記憶體

共享記憶體的幾乎可以認為沒有上限,它也是不侷限與父子程序,採用跟訊息佇列類似的定位方式,因為記憶體是共享的,不存在任何單向的限制,最大的問題就是需要應用程式自己做互斥,有如下幾種方案

1 只適用兩個程序共享,在記憶體中放乙個標誌位,一定要宣告為volatile,大家基於標誌位來互斥,例如為0時第乙個可以寫,第二個就等待,為1時第乙個等待,第二個可以寫/讀

2 也只適用兩個程序,是用訊號,大家等待不同的訊號,第乙個寫完了傳送訊號2,等待訊號1,第二個等待訊號2,收到後讀取/寫入完,傳送訊號1,它不是用更多程序是因為雖然父程序可以向不同子程序分別傳送訊號,但是子程序收到訊號會同時訪問共享記憶體,產生不同子程序間的競態條件,如果用多塊共享記憶體,又存在子程序傳送結果通知訊號時,父程序收到訊號後,不知道是誰傳送,也意味著不知道該訪問哪塊共享記憶體,即使子程序傳送不同的結果通知訊號,因為等待訊號的一定是阻塞的,如果某個子程序意外終止,父程序將永遠阻塞下去,而不能超時處理

3 採用訊號量或者msgctl自己的加鎖、解鎖功能,不過後者只適用於linux

------總結

管道是最弱的,只適合有限場景;

訊息佇列能適合大部分場景,缺點是預設緩衝也比較小,不過這個可以調整,前提是你有管理員許可權;

具體見共享記憶體是最強大的,只是要做互斥

管道 訊息佇列 共享記憶體

管道通訊 pipe 管道通訊方式的中間介質是檔案,通常稱這種檔案為管道檔案。兩個程序利用管道檔案進行通訊時,乙個程序為寫程序,另乙個程序為讀程序。寫程序通過寫端 傳送端 往管道檔案中寫入資訊 讀程序通過讀端 接收端 從管道檔案中讀取資訊。兩個程序協調不斷地進行寫 讀,便會構成雙方通過管道傳遞資訊的流...

linux 管道 訊息佇列 共享記憶體的對比

管道 管道的優點是不需要加鎖,缺點是預設緩衝區太小,只有4k,同時只適合父子程序間通訊,而且乙個管道只適合單向通訊,如果要雙向通訊需要建立兩個。而且不適合多個子程序,因為訊息會亂,它的傳送接收機制是用read write這種適用流的,缺點是資料本身沒有邊界,需要應用程式自己解釋,而一般訊息大多是乙個...

Linux 記憶體共享與訊息佇列

共享記憶體 共享共存區域是被多個程序共享的一部分物理記憶體。如果多個程序都 把該記憶體區域對映到自己的虛擬位址空間,則這些程序就都可以直接 訪問該共享記憶體區域,從而可以通過該區域進行通訊。共享記憶體是進 程間共享資料的一種最快的方法,乙個程序向共享記憶體區域寫入了數 據,共享這個記憶體區域的所有程...