程序間通訊IPC

2021-07-29 02:29:23 字數 3981 閱讀 6787

乙個大型的應用系統,往往需要眾多程序協作,程序間通訊的重要性顯而易見。

首先,程序間通訊至少可以通過傳送開啟檔案來實現,不同的程序通過乙個或多個檔案來傳遞資訊,事實上,在很多應用系統裡,都使用了這種方法。但一般說來, 程序間通訊(ipc:interprocess communication)不包括這種似乎比較低階的通訊方法。unix系統中實現程序間通訊的方法很多,而且不幸的是,極少方法能在所有的unix系統中進行移植(唯一一種是半雙工的管道,這也是最原始的一種通訊方式)。而linux作為一種新興的作業系統,幾乎支援所有的unix下常用的程序間通訊方法:管道、訊號、訊息佇列、共享記憶體、訊號量、套介面等等。

管道

1. 管道通訊 是 單 向 的,有 固定 的 讀端 和 寫端 。

2. 資料 被 進 程從管道 讀出後 , 在管道 中 該 資料 就 不 存 在 了 。

3. 當程序去讀取空管道的 時 候,進 程 會阻塞 。

4. 當程序往滿管道寫入資料時,進 程 會阻塞 。

5. 管道 容量為 為64kb

管道常用於兩個方面:(1)在shell中時常會用到管道(作為輸入輸入的重定向),在這種應用方式下,管道的建立對於使用者來說是透明的;(2)用於具有親緣關係的程序間通訊,使用者自己建立管道,並完成讀寫操作。

無名管道:

當乙個管道建立時,會建立兩個檔案描述符fd[0]、fd[1]。其中fd[0]固定用於讀管道,fd[1]固定用於寫管道。把fd[0] fd[1]當做檔案來操作,一般檔案的i/o函式都可以用於管道,如close、read、write等等。它不屬於某種檔案系統,而是自立門戶,單獨構成一種檔案系統,並且只存在與記憶體中。

只能用於有親緣關係的程序之間的通訊。半雙工通訊模式,具有固定的讀端和寫端。

讀端固定:1、寫端存在:如果無輸入資料,阻塞,如果有輸入資料輸入多少輸出多少

2、寫端不存在:如果管道裡有資料有多少讀多少,如果管道裡沒有資料立即返回0

寫端固定:1、讀端存在:如果管道空間足夠大,可以一直向管道寫內容。

如果管道空間不足,只能輸入前面若干個滿足管道空間大小的一些字元,剩下的丟失

寫端固定:2、讀端不存在:系統預設傳送訊號sigpipe結束當前程序。程序結束管道將不存在。

在向管道寫入資料時,至少應該存在某乙個程序,其中管道讀端沒有被關閉,否則就會出現管道斷裂,程序收到了sigpipe訊號,預設動作是程序終止)

有名管道:

有名管道可以使互不相關的兩個程序互相通訊,可以通過路徑名來指出,並在檔案系統中可見。

有名管道遵循先進先出規則。程序通過檔案io操作有名管道。一般檔案的i/o函式都可以用於fifo,如close、read、write等等。

fifo空間不足 寫程序阻塞; fifo內沒有資料,讀程序阻塞。  

單獨執行讀端或者寫端都會阻塞,先執行哪個程序就在哪個程序中建立管道。

對管道及fifo的讀總是從開始處返回資料,對它們的寫則把資料新增到末尾。它們不支援諸如lseek()等檔案定位操作。

共享記憶體:

共享記憶體是一種最為高效的程序間通訊方式,程序可以直接讀寫記憶體,而不需要任何資料的拷貝。

核心專門留出了一塊記憶體區,可以由需要訪問的程序將其對映到自己的私有位址空間

由於多個程序共享一段記憶體,因此也需要依靠某種同步機制,如互斥鎖和訊號量等。

讀出共享記憶體後 讀出的值還在共享記憶體中  再次寫入後原值被覆蓋,用fgets寫入會在字串後面自動加'\0'。

所以下次輸出並不輸出'\0'後面的字元。

訊息佇列

訊息佇列就是乙個訊息的鍊錶。可以把訊息看作乙個記錄,具有特定的格式以及特定的優先順序。

訊息的傳送者和接收者不需要同時與訊息佇列互交。訊息會儲存在佇列中,直到接收者取回它。

訊息佇列可以單獨的執行讀或寫操作,且讀出後訊息佇列裡的值被清除。

訊息佇列允許接收者在訊息傳送很長時間後再取回訊息,但訊息佇列的這個特點,也造成了乙個缺點,就是接收者必須輪詢訊息佇列,才能收到最近的訊息。

訊息佇列克服了訊號承載資訊量少,管道只能承載無格式位元組流以及緩衝區大小受限等缺點。但訊息佇列仍然有大小限制。

小結:訊息佇列與管道以及有名管道相比,具有更大的靈活性,首先,它提供有格式(char)位元組流,有利於減少開發人員的工作量;其次,訊息具有型別,在實際應用中,可作為優先順序使用。這兩點是管道以及有名管道所不能比的。同樣,訊息佇列可以在幾個程序間復用,而不管這幾個程序是否具有親緣關係,這一點與有名管道很相似;但訊息佇列是隨核心持續的,與有名管道(隨程序持續)相比,生命力更強,應用空間更大。

訊息佇列就是乙個訊息的鍊錶。不同型別type把訊息新增到已開啟的訊息佇列末尾即鍊錶末尾。

相同型別type會把訊息以fifo機制存放在這個type下。

訊息佇列可以單獨的執行讀或寫操作,且讀出後訊息佇列裡的值被清除。

訊號:

訊號是在軟體層次上對中斷機制的一種模擬,是一種非同步(不確定事情發生時間)通訊方式。

訊號可以直接進行使用者空間程序和核心程序之間的互動。如果乙個訊號被程序設定為阻塞,則該訊號的傳遞被延遲

知道其阻塞被取消時才被傳遞給程序。

sigkill  sigstop不能被忽略

2 sigint   ctry + c傳送int訊號(sigint);預設情況下,這會導致程序終止。

3 sigquit ctry + \傳送quit訊號(sigquit); 缺省會導致程序終止並且將記憶體中的資訊轉儲到硬碟(核心轉儲)。

9 sigkill   該訊號用於立即結束程式的執行,不能被阻塞處理或忽略。

10 sigusr1  自定義訊號。通過signal()函式確定訊號的作用

12 sigusr2  自定義訊號。同上         

13 sigpipe  管道讀端不存在時,向管道中寫入資料的程序會收到核心傳來的sigpipe訊號。

14 sigalrm  alarm對程序設定乙個定時器,定時時間到核心就向該程序傳送sigalarm訊號,預設終止這個程序

15 sigterm  使用kill的時候後面沒有訊號  預設是15(sigterm)終止乙個程序    kill 程序號        

17 sigchld  子程序改變狀態時,父程序會收這個訊號。

18 sigcont  使乙個t(暫停)狀態的程序繼續執行(處於後台執行)。

19 sigstop  該訊號用於暫停乙個程序,且不能被阻塞處理或忽略。           

20 sigtstp  ctry + z 傳送sigtstp訊號,缺省會導致程序掛起。

訊號燈:

也叫訊號量,它是不同程序間或乙個給定程序內部不同執行緒間同步和互斥的機制。

二值訊號燈:值為0或1,資源可用時值為1,不可用時值為0.

計數訊號燈:值在0到n之間,用來統計資源,其值代表可用資源數

等待操作是等待訊號燈的值變為大於0,然後將其減1,而釋放操作則相反,用來喚醒等待資源的程序或執行緒。

程序間通訊方式比較:

pipe:具有親緣關係的程序間,單工,資料在記憶體中。    (管道)

fifo:可用於任意程序間,雙工,有檔名,資料在記憶體。(有名管道)

signal:唯一的非同步通訊方式。                        (訊號)    

shm:效率最高,直接訪問記憶體,需要同步,互斥機制。   (共享記憶體)

msg:常用於cs模式中,按訊息型別訪問,可有優先順序。   (訊息佇列)

sem:配合共享記憶體使用,用以實現同步和互斥。         (訊號燈)

管道一般用於資料傳輸,訊號用於事件通知,訊號燈用於資源共享

1.隨程序持續:ipc一直存在到開啟ipc物件的最後乙個程序關閉該物件為止。如管道和有名管道;

2.隨核心持續:ipc一直持續到核心重新自舉或者顯示刪除該物件為止。如訊息佇列、訊號燈以及共享記憶體等;

3.隨檔案系統持續:ipc一直持續到顯示刪除該物件為止。

程序間通訊IPC

這兩天學習了 unix 的程序間通訊 ipc,這裡面有幾個很重要的基本概念,特別是訊息佇列和我的畢設很有關係,因此多說幾句。以前學習的程序間通訊方式,一般都是經由 fork 或exec 開啟檔案,或經過檔案系統。而 ipc是程序間通訊方式的統稱。下面一一道來。一 管道 管道是最老的 ipc形式。管道...

程序間通訊 IPC

part2 index1.html part2 index2.html linux至少支援如下ipc機制 同時支援posix和system v方式 streams ipc機制,linux本身不支援,有乙個單獨的安裝包 可以跨pc的程序通訊 互斥鎖或條件變數 動態初始化 不能使靜態分配 在共享記憶體中...

程序間通訊IPC

關係程序的程序間通訊 父子關係 沒有關係的程序通過訊號進行通訊 管道比共享記憶體的實時性好 linux下預設遵守posix的程序間通訊匿名管道 管道pipe 命名管道 fifo 套接字 高階ipc 不同主機間通訊 管道通訊最常見的ipc方式 int pipe int fd 2 返回 成功為0 失敗為...