1. 程式人生 > >管道、訊息佇列、共享記憶體之間的區別與聯絡

管道、訊息佇列、共享記憶體之間的區別與聯絡

 管道和訊息佇列的區別

管道(PIPE)

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

管道分為匿名管道和命名管道。

(1)匿名管道:管道是半雙工的,資料只能單向通訊;需要雙方通訊時,需要建立起兩個管道;只能用於父子程序或者兄弟程序之間(具有親緣關係的程序)。

(2)命名管道:可在同一臺計算機的不同程序之間或在跨越一個網路的不同計算機的不同程序之間,支援可靠的、單向或雙向的

資料通訊

      不同於匿名管道之處在於它提供一個路徑名與之關聯,以FIFO的檔案形式存在於檔案系統中。這樣,即使與FIFO的建立程序不存在親緣關係的程序,只要可以訪問該路徑,就能夠彼此通過FIFO相互通訊(能夠訪問該路徑的程序以及FIFO的建立程序之間),因此,通過FIFO不相關的程序也能交換資料。值得注意的是,FIFO嚴格遵循先進先出(first in first out),對管道及FIFO的讀總是從開始處返回資料,對它們的寫則把資料新增到末尾。

     利用系統呼叫pipe()建立一個無名管道檔案,通常稱為無名管道或PIPE;利用系統呼叫mknod()建立一個命名管道檔案,通常稱為有名管道或FIFO。

PIPE是一種非永久性的管道通訊機構,當它訪問的程序全部終止時,它也將隨之被撤消;它也不能用於不同族系的程序之間的通訊。而FIFO是一種永久的管道通訊機構,它可以彌補PIPE的不足。管道檔案被建立後,使用open()將檔案進行開啟,然後便可對它進行讀寫操作,通過系統呼叫write()和read()來實現。通訊完畢後,可使用close()將管道檔案關閉。因為匿名管道的檔案是記憶體中的特殊檔案,而且是不可見的,命名管道的檔案是硬碟上的裝置檔案,是可見的。

訊息佇列(message queue)

      訊息佇列與命名管道類似,但少了開啟和關閉管道方面的複雜性。使用訊息佇列並未解決我們在使用命名管道時遇到的一些問題,

如管道滿時的阻塞問題。訊息佇列提供了一種在兩個不相關程序間傳遞資料的簡單有效的方法。與命名管道相比:訊息佇列的優勢在於,它獨立於傳送和接收程序而存在,這消除了在同步命名管道的開啟和關閉時可能產生的一些困難。訊息佇列提供了一種從一個程序向另一個程序傳送一個數據塊的方法。而且,每個資料塊被認為含有一個型別,接收程序可以獨立地接收含有不同型別值的資料塊。

優點:       A. 我們可以通過傳送訊息來幾乎完全避免命名管道的同步和阻塞問題。       B. 我們可以用一些方法來提前檢視緊急訊息。 缺點:       A. 與管道一樣,每個資料塊有一個最大長度的限制。       B. 系統中所有佇列所包含的全部資料塊的總長度也有一個上限。 Linux系統中有兩個巨集定義:  MSGMAX, 以位元組為單位,定義了一條訊息的最大長度。  MSGMNB, 以位元組為單位,定義了一個佇列的最大長度。 限制:       由於訊息緩衝機制中所使用的緩衝區為共用緩衝區,因此使用訊息緩衝機制傳送資料時,兩通訊程序必須滿足如下條件。      (1)在傳送程序把寫入訊息的緩衝區掛入訊息佇列時,應禁止其他程序對訊息佇列的訪問,否則,將引起訊息佇列的混亂。同理,當接收程序正從訊息佇列中取訊息時,也應禁止其他程序對該佇列的訪問。      (2)當緩衝區中無訊息存在時,接收程序不能接收任何訊息;而傳送程序是否可以傳送訊息,則只由傳送程序是否能夠申請緩衝區決定。

=============================================================================================

共享記憶體比管道和訊息佇列效率高的原因

    共享記憶體是程序間通訊中最簡單的方式之一。共享記憶體允許兩個或更多程序訪問同一塊記憶體,就如同 malloc() 函式向不同程序返回了指向同一個實體記憶體區域的指標。當一個程序改變了這塊地址中的內容的時候,其它程序都會察覺到這個更改。

    因為所有程序共享同一塊記憶體,共享記憶體在各種程序間通訊方式中具有最高的效率。訪問共享記憶體區域和訪問程序獨有的記憶體區域一樣快,並不需要通過系統呼叫或者其它需要切入核心的過程來完成。同時它也避免了對資料的各種不必要的複製。
    因為系統核心沒有對訪問共享記憶體進行同步,您必須提供自己的同步措施。例如,在資料被寫入之前不允許程序從共享記憶體中讀取資訊、不允許兩個程序同時向同一個共享記憶體地址寫入資料等。解決這些問題的常用方法是通過使用訊號量進行同步。

    共享記憶體塊提供了在任意數量的程序之間進行高效雙向通訊的機制。每個使用者都可以讀取寫入資料,但是所有程式之間必須達成並遵守一定的協議,以防止諸如在讀取資訊之前覆寫記憶體空間等競爭狀態的出現。不幸的是,Linux無法嚴格保證提供對共享記憶體塊的獨佔訪問,甚至是在您通過使用IPC_PRIVATE建立新的共享記憶體塊的時候也不能保證訪問的獨佔性。 同時,多個使用共享記憶體塊的程序之間必須協調使用同一個鍵值。     

       共享記憶體區是最快的可用IPC形式,一旦這樣的記憶體區對映到共享它的程序的地址空間,這些程序間資料的傳遞就不再通過執行任何進入核心的系統呼叫來傳遞彼此的資料,節省了時間。
       共享記憶體和訊息佇列,FIFO,管道傳遞訊息的區別:
       ——訊息佇列,FIFO,管道的訊息傳遞方式一般為
          1:伺服器得到輸入
          2:通過管道,訊息佇列寫入資料,通常需要從程序拷貝到核心。
          3:客戶從核心拷貝到程序
          4:然後再從程序中拷貝到輸出檔案
      上述過程通常要經過4次拷貝,才能完成檔案的傳遞。
       ——共享記憶體只需要
           1:從輸入檔案到共享記憶體區
           2:從共享記憶體區輸出到檔案

上述過程不涉及到核心的拷貝,所以花的時間較少。

相關推薦

管道訊息佇列共享記憶體之間區別聯絡

程序間通訊的目的:                  資料傳輸:一個程序需要將它的資料傳送給另一個程序,傳送的資料量在一個位元組到幾兆位元組之間。        共享資料:多個程序想要操作共享資料,一個程序對共享資料的修改,別的程序應該立刻看到。        通知事件:一

程序間通訊——管道訊息佇列共享記憶體

程序間通訊的本質是讓兩個不相干的程序看到同一份資源。這個資源是由作業系統提供的一個檔案。程序間通訊的目的:1.資料傳輸:一個程序需要將它 的資料傳送給另一個程序。2.資源共享:多個程序之間共享同樣的資源。3.通知事件:一個程序需要向另一個(組)程序傳送訊息,通知它們發生了

管道訊息佇列共享記憶體之間區別聯絡

 管道和訊息佇列的區別 管道(PIPE)      管道通訊方式的中間介質是檔案,通常稱這種檔案為管道檔案。兩個程序利用管道檔案進行通訊時,一個程序為寫程序,另一個程序為讀程序。寫程序通過寫

作業系統(11)程序--程序通訊:訊號管道訊息佇列共享記憶體

文章目錄 1. 程序通訊相關概念 1. 通訊流程、屬性、鏈路 2. 程序通訊方式:直接通訊、間接通訊 2. 程序通訊的機制 1. 訊號 2. 管道 3. 訊息佇列

程序間通訊的方式——訊號管道訊息佇列共享記憶體

多程序: 首先,先來講一下fork之後,發生了什麼事情。 由fork建立的新程序被稱為子程序(child process)。該函式被呼叫一次,但返回兩次。兩次返回的區別是子程序的返回值是0,而父程序的返回值則是新程序(子程序)的程序 id。將子程序id返回給父程序的理由是

程序通訊---管道訊息佇列共享記憶體

程序通訊分為低階通訊和高階通訊。 低階通訊是指程序互斥與同步,包括訊號、訊號量、管程等。 高階通訊方式有管道、訊息佇列、共享記憶體以及網路通訊中的套接字。 匿名管道PIPE: 管道是連線兩個程序的檔案,

管道訊息佇列共享記憶體訊號量的特點

在之前我們已經瞭解過了程序間通訊的幾種方式:管道、訊息佇列、共享記憶體以及訊號量。今天我們就來總結一下這幾種方式的各自的特點分別是什麼,和他們相應的應用場景。也是對於這個知識點的一個複習和鞏固。 Q1

人工智慧(PythonNet)—— 程序間通訊(管道訊息佇列共享記憶體訊號訊號量套接字)

一、程序間通訊        程序間通訊(IPC,InterProcess Communication)是指在不同程序之間傳播或交換資訊。        由於每個程序的空間是互相獨立的,程序之間無法互相直接獲取彼此的資源,故引入程序間通訊來實現程序間的資源互動。       

程序間通訊(IPC)-管道訊息佇列共享記憶體訊號訊號量套接字

多程序:首先,先來講一下fork之後,發生了什麼事情。由fork建立的新程序被稱為子程序(child process)。該函式被呼叫一次,但返回兩次。兩次返回的區別是子程序的返回值是0,而父程序的返回值則是新程序(子程序)的程序 id。將子程序id返回給父程序的理由是:因為一

Linux下程序間通訊方式之管道訊號共享記憶體訊息佇列訊號量套接字

/* 1,程序間通訊 (IPC ) Inter-Process Communication   比較好理解概念的就是程序間通訊就是在不同程序之間傳播或交換資訊。 2,linux下IPC機制的分類:管道、訊號、共享記憶體、訊息佇列、訊號量、套接字 3,這篇主要說說管

共享記憶體訊息佇列訊號量之ipcs命令詳解

中介軟體中我們常通過啟動多個程序來提高其執行的穩定性,而共享記憶體、訊息佇列、訊號量等技術保證了多程序間的通訊。 在Linux系統中通過自帶的ipcs命令工具,可檢視當前系統中以上三項的使用情況,從而利於定位多程序通訊中出現的通訊問題。 ipcs -h檢視該命令的使用幫助

Linux-程序通訊-訊息佇列/訊號燈/共享記憶體

訊息佇列     訊息佇列提供了程序間傳送資料塊的方法,每個資料塊都可以被認為是有一個型別,接受者接受的資料塊可以有不同的型別;我們可以通過傳送訊息來避免命名管道的同步和阻塞問題;訊息佇列與命名管道一樣,每個資料塊都有一個最大長度的限制;我們可以將每個資料塊當作是一

boost程序間通訊常用開發一篇全(訊息佇列共享記憶體,訊號)

本文概要:         敏捷開發大家想必知道而且評價甚高,縮短開發週期,提高開發質量。將大工程獨立為不同的小app開發,整個開發過程,程式可用可測,所以提高了整體的質量。基於這種開發模式和開發理念,程序間通訊必然是童鞋們必掌握技能之一了,而boost庫是眾多庫中平臺支援

程序間通訊的訊息佇列共享記憶體方式的實現

共享記憶體方式使用QSharedMemory 和QSystemSemaphore兩個類實現 一個程序往共享記憶體空間中寫,一個程序往共享記憶體空間中讀 兩程序通訊時: 向共享記憶體中提供資料的一方: 1,定義QSharedMemory shareMemory,並設定標誌名shareMemory.setKey(

C語言程序通訊訊息佇列共享記憶體(5)

歡迎加入QQ:498903810 一起交流、討論知識,裡面有大佬,也有小白,天下碼農一家親,大家一起討論進步。 訊息佇列 訊息佇列:預設傳送端將資訊放在前一個資訊後面,接收訊息端可以指

Linux環境變數使用者變數和shell變數的區別聯絡

1.shell簡介 shell是指為使用者提供操作介面的軟體,不同作業系統有著不同的shell,同一個作業系統也有著不同的shell。shell分為兩大類:圖形介面shell和命令列式shell。 圖形介面shell:windows作業系統下常用的windows Expl

linux下系統呼叫API系統命令,核心函式的區別聯絡

1.系統呼叫: 應用程式和核心間的橋樑,是應用程式訪問核心的入口點;但通常情況下,應用程式通過作業系統提供的API進行程式設計而不是使用系統呼叫直接程式設計; linux的全部系統呼叫加起來大約只有250個左右。 2.API:   API常以c庫(libc)的形式提供,

mmap和shm共享記憶體區別聯絡

共享記憶體的建立 根據理論:  1. 共享記憶體允許兩個或多個程序共享一給定的儲存區,因為資料不需要來回複製,所以是最快的一種程序間通訊機制。共享記憶體可以通過mmap()對映普通檔案(特殊情況下還可以採用匿名對映)機制實現,也可以通過系統V共享記憶體機制實現。應用介面

day_13_管道共享記憶體訊息佇列

一、使用管道實現程序間的通訊 1.1 基本概念   管道本質上還是以檔案作為媒介,只是該檔案比較特殊,叫做管道檔案而已;   管道主要分為兩大類:有名管道 和 無名管道;     有名管道 - - - - - - 可以用於任意兩個程序間的通

Linux 學習筆記—程序通訊之 訊息佇列訊號量共享記憶體的概念區別聯絡

2.5 訊息佇列(Message queues) 訊息佇列是核心地址空間中的內部連結串列,通過linux核心在各個程序直接傳遞內容,訊息順序地傳送到訊息佇列中,並以幾種不同的方式從佇列中獲得,每個訊息佇列可以用IPC識別符號唯一地進行識別。核心中的訊息佇列是通過