1、資料傳輸:乙個程序需要將它的資料傳送給另乙個程序。
2、資源共享:多個程序之間共享同樣的資源。
3、通知事件:乙個程序需要向另乙個或一組程序傳送資訊,通知它們發生了某種事情。
4、程序控制:有些程序希望完全控制另乙個程序。此時控制程序能夠攔截另乙個程序的所有操作,並能夠及時知道它的狀態改變。
管道是單向的、先進先出的、無結構的、固定大小的位元組流。
建立管道:呼叫pipe函式在核心開闢一塊緩衝區,稱為管道,pipe函式呼叫成功返回1,失敗返回0。
1、它有乙個讀端乙個寫端。
2、通過filedes引數傳出給使用者程式兩個檔案描述符:filedes[0]指向讀端,filedes[1]指向寫端。
3、向這個檔案讀寫資料其實是在讀寫核心緩衝區。
4、單個管道只能單向通訊,一端用於讀,而另一端用於寫。如果要實現程序雙向通訊,必須建立一對管道。
管道的侷限性:
1、歷史上,管道是半全雙工,(即資料只能在乙個方向上流動,只能是一端寫,一端讀)。
2、只能在有公共祖先的程序之間使用(在父子程序或兄弟程序間使用)——普通管道。
3、讀資料的同時也將資料從管道移走,因此,管道不能用來對多個接受者廣播資料。
4、管道中的資料被當做位元組流,因此無法識別資訊的邊界。
5、如果乙個管道有多個讀程序,那麼寫程序不能傳送資料到指定的讀程序,同樣,如果有多個寫程序,那麼沒有辦法判斷是哪乙個傳送資料。
建立命名管道的系統函式有兩個:mkfifo和mknod,呼叫成功返回0,失敗返回-1,兩個函式的原型如下:
通訊:
1、父程序呼叫pipe函式開闢管道,得到兩個檔案描述符分別指向管道的兩端。
2、父程序呼叫fork函式建立子程序,同樣子程序也有兩個檔案描述符指向該管道的兩端。
3、父程序關閉讀端,子程序關閉寫端,父程序可以往管道裡寫,子程序可以從管道中讀,管道是用環形佇列實現的,資料從寫端流入讀端流出,這樣就實現程序間通訊。
linux必須保證管道的寫和讀步調一致:linux使用鎖、等待佇列、和訊號實現同步。
訊息佇列提供從乙個程序到另乙個程序傳送資料塊的方法。
訊息佇列與管道的區別:
1、訊息佇列是基於訊息的,管道是基於位元組流的。
2、訊息佇列傳送訊息來避免管道的同步和阻塞問題。
3、訊息佇列的讀取不一定是先進先出。
4、每個訊息佇列的最大長度有上限,給定訊息總的位元組數有上限,訊息佇列總訊息數有上限。
核心為每個ipc物件維護乙個資料結構,都包括ipc_perm資料結構。(訊息佇列、訊號量、共享記憶體都有這個資料結構)。
struct ipc_perm
;訊息佇列就是乙個訊息的乙個鍊錶,允許乙個或多個程序向它寫訊息,乙個或多個程序從中讀訊息。
linux提供訊息佇列的操作:
1、建立或獲得訊息佇列:
函式原型:
int sys_msgget (key_t key, int msg***);
引數:key:
是乙個鍵值,可以認為是乙個埠號,也可以由函式ftok生成。
msg***:是乙個標誌。
msg***:
ipc_creat:如果ipc不存在,則建立乙個ipc資源,否則開啟操作。
ipc_excl: ipc_creat和ipc_excl可以保證所得物件是新建的,而不是開啟的已有物件。
工作過程如下:
1) 如果key == ipc_private,則申請一塊記憶體,建立乙個新的訊息佇列( 資料結構msqid_ds),將其初始化後加入到msgque向量表中的某個空位置處,返回識別符號。
2) 在msgque向量表中找鍵值為key的 訊息佇列,如果沒有找到,結果有二:
a、 msg***表示不建立新的佇列,則錯誤返回。
b、 msg***表示要建立新的佇列,則建立新 訊息佇列,建立過程如1)。
3) 如果在msgque向量表中找到了鍵值為key的 訊息佇列,則有以下情況:
a、如果msg***表示一定要建立新的 訊息佇列而且不允許有相同鍵值的佇列存在,則錯誤返回。
b、如果找到的佇列是不能用的或已損壞的佇列,則錯誤返回。
c、認證和訪問許可權檢查,如果該佇列不允許msg***要求的訪問,則錯誤返回。
d、正常,返回佇列的 識別符號。
2、向佇列讀/寫訊息
函式原型:
該函式做如下工作:
1) 該 訊息佇列在向量msgque中的索引是id = (unsigned int) msqid % msgmni,認證檢查(許可權、模式),合法性檢查(型別、大小等)。
2) 如果 佇列已滿,以可中斷等待狀態(task_interruptible)將當前程序掛起在wwait 等待佇列上。
3) 申請一塊空間,大小為乙個訊息 資料結構加上訊息大小,在其上建立乙個訊息資料結構struct msg,將訊息緩衝區中的訊息內容拷貝到該記憶體塊中訊息頭的後面(從 使用者空間拷貝到 核心空間)。
4) 將訊息資料結構加入到 訊息佇列的隊尾,修改佇列的相應引數(大小等)。
5) 喚醒在該 訊息佇列的rwait程序佇列上等待讀的程序。
6) 返回。
msgrcv:
該函式做如下工作:
1) 該訊息佇列在向量msgque中的索引是id = (unsigned int) msqid % msgmni,認證檢查(許可權、模式),合法性檢查。
2)根據msgtyp和msg***搜尋 訊息佇列,情況有二:
3)如果找不到所要的訊息,則以可中斷等待狀態(task_interruptible)將當前程序掛起在rwait等待佇列上。
4)如果找到所要的訊息,則將訊息從 佇列中摘下,調整佇列引數,喚醒該 訊息佇列的wwait程序佇列上等待寫的程序,將訊息內容拷貝到 使用者空間的訊息緩衝區msgp中,釋放核心中該訊息所占用的空間,返回。
訊號量的本質是一種資料操作鎖,它本身不具有資料交換的功能,而是通過控制其他的通訊資源來實現程序間通訊,它本身只是一種外部資源的標識。訊號量在此過程中負責資料操作的互斥、同步等功能。
使用訊號量的原因:為了防止出現多個程式同時訪問乙個共享資源引發的一系列問題。任一時刻只能有乙個執行執行緒訪問**的臨界區域。
訊號量只能進行兩種操作等待和傳送訊號即p(sv)和v(sv)。
通常由乙個程序建立。其他程序對這個記憶體進行讀寫,得到共享記憶體通常是通過記憶體對映。
linux本身無法對其同步,需要程式自己來對共享記憶體做出同步計算,何種同步很多時候就是用訊號量實現的。
Linux程序間通訊
程序間通訊 ipc interprocess communication 基本機制 訊號 管道及命名管道 訊息佇列 共享主存 訊號量 套接字。訊號 全稱軟中斷訊號,是在軟體層次上對中斷機制的一種模擬,它也是程序間通訊機制中唯一的非同步通訊機制。linux訊號處理函式可分為訊號安裝函式 訊號傳送函式和...
Linux程序間通訊
謝謝nonoob糾錯 我們在linux訊號基礎中已經說明,訊號可以看作一種粗糙的程序間通訊 ipc,interprocess communication 的方式,用以向程序封閉的記憶體空間傳遞資訊。為了讓程序間傳遞更多的資訊量,我們需要其他的程序間通訊方式。這些程序間通訊方式可以分為兩種 1.管道與...
Linux程序間通訊
謝謝nonoob糾錯 我們在linux訊號基礎中已經說明,訊號可以看作一種粗糙的程序間通訊 ipc,interprocess communication 的方式,用以向程序封閉的記憶體空間傳遞資訊。為了讓程序間傳遞更多的資訊量,我們需要其他的程序間通訊方式。這些程序間通訊方式可以分為兩種 1.管道與...