linux程序間通訊之訊息傳遞

2021-06-22 22:01:47 字數 2719 閱讀 5432

linux 程序間通訊中訊息傳遞主要分為管道,fifo,訊息佇列

(1)管道

管道由pipe函式建立,提供乙個單路(單向)資料流。pipe函式返回兩個檔案描述符:fd[0]和fd[1]。前者開啟來讀,後者開啟來寫。管道沒有名字,所以只能由有親緣關係的程序使用。儘管管道是由單個程序建立的,它卻很少在單個程序內使用。管道的典型用途為兩個不同程序(乙個是父程序,乙個是子程序)提供程序間的通訊手段。首先,由乙個程序(它將成為父程序)建立乙個管道後呼叫fork派生乙個自身的副本。接著,父程序關閉這個管道的讀出端,子程序關閉同一管道的寫入端。或者父程序關閉這個管道的寫入端,子程序關閉同一管道的讀出端。這就在父子程序間提供了乙個單向資料流。

(2)fifo

fifo指代先進先出(first in,first out),linux中的fifo類似管道。它是乙個單向(半雙工)資料流。不同於管道的是,每個fifo有乙個路徑名與之關聯,從而允許無親緣關係的程序訪問同乙個fifo。fifo也稱為有名管道。fifo由mkfifo函式建立。其中pathname是乙個普通的unix路徑名,它是該fifo的名字。mkfifo 函式已隱含指定 o_creat|o_excl. 也就是說,它那麼建立乙個新的fifo,要麼返回乙個eexist錯誤(如果所指定的名字的fifo已經存在)。如果不想希望建立乙個新的fifo,那就改為呼叫open而不是mkfifo.要開啟乙個已存在的fifo或建立乙個新的fifo,應先呼叫mkfifo,再檢查它是否返回eexist錯誤,若返回該錯誤則改為呼叫open.mkfifo 命令也能建立fifo。可以從shell指令碼或命令列中使用它。在建立出乙個fifo後,它必須或者開啟來讀,或者開啟來寫,所用的可以是open函式,也可以是某個標準i/o開啟函式。fifo不能開啟來既讀又寫,因為它是半雙工的。對管道或fifo的write總是往末尾新增資料,對它們的read則總是從開頭返回資料。如果對管道或fifo呼叫lseek,那就返回espipe錯誤。

(3)posix 訊息佇列

訊息佇列可認為是乙個訊息鍊錶。有足夠寫許可權的執行緒可往佇列中放置訊息,有足夠讀許可權的執行緒可從佇列中取走訊息。每個訊息都是乙個記錄,它由傳送者賦予乙個優先順序。在某個程序往乙個佇列寫入訊息之前,並不需要另外某個程序在該佇列上等待訊息的到達。這跟管道和fifo是相反的,對後者來說,除非讀出者已存在,否則先有寫入者是沒有意義的。乙個程序可以往某個佇列寫入一些訊息,然後終止,再讓另外乙個程序在以後某個時刻讀出這些訊息。訊息佇列具有隨核心的持續性,這跟管道和fifo不一樣。posix訊息佇列和system v訊息佇列。這兩組函式間存在許多相似性,但也有主要的區別

1. 對posix訊息佇列的讀總是返回最高優先順序的最早訊息,對system v訊息佇列的讀則可以返回任意指定優先順序的訊息。

2.當往乙個空佇列放置乙個訊息時,posix 訊息佇列允許產生乙個訊號或啟動乙個執行緒。system v訊息佇列則不提供類似機制。

佇列中的每個訊息具有如下屬性:

1.乙個無符號整數優先順序(posix)或乙個長整數型別(system v).

2.訊息的資料部分長度(可以為0).

3.資料本身(如果長度大於0)

函式介面

1. mqd_t mq_open(const char *name,int oflag,...)

mq_open函式建立乙個新的訊息佇列或開啟乙個已存在的訊息佇列

2.int mq_close(mqd_t mqdes);

mq_close函式關閉乙個訊息佇列。

3.int mq_unlink(const char *name);

從系統中刪除用作第乙個引數的某個name.

4. int mq_getattr(mqd_t mqdes,struct mq_attr *attr);

int mq_setattr(mqd_t mqdes,const struct mq_attr *attr,struct mq_attr *oattr);

每個訊息佇列有四個屬性,mq_getattr返回所有這些屬性,mq_setattr則設定其中某個屬性。

struct mq_attr;

5.int mq_send(mqd_t mqdes,const char *ptr,size_t len,unsigned int prio);

int mq_receive(mqd_t mqdes,char *ptr,size_t len,unsigned int *priop);

mq_send函式往訊息佇列中寫入訊息,mq_receive函式從訊息佇列中讀出訊息。

6.int mq_notify(mqd_t mqdes,const struct sigevent *motification);

結構體:

union sigval;

struct sigevent

;mq_notify函式為指定佇列建立或刪除非同步事件通知。一些普遍適用於該函式的若干規則

1).如果notification引數非空,那麼當前程序希望在乙個訊息達到所指定的先前為空的佇列時得到通知。我們說"該程序被註冊為接收該佇列的通知"。

2).如果notification引數為空指標,而且當前程序目前被註冊為接收所指定佇列的通知,那麼已存在的註冊將被撤銷。

3).任意時刻只有乙個程序可以被註冊為接收某個給定佇列的通知。

4).當有乙個訊息達到某個先前為空的佇列,而且已有乙個程序被註冊為接收該佇列的通知時,只有在沒有任何執行緒阻塞在該佇列的mq_receive呼叫中的前提下,通知才會發出。這就是說,在mq_receive呼叫中的阻塞比任何通知的註冊都優先。

5).當該通知被傳送給它的註冊程序時,其註冊即被撤銷。該程序必須再次呼叫mq_notify以重新註冊(想要的話)。

linux程序間通訊之訊息佇列

訊息佇列就是乙個訊息的鍊錶。可以把訊息看作乙個記錄,具有特定的格式以及特定的優先順序。對訊息佇列有寫許可權的程序可以向中按照一定的規則新增新訊息 對訊息佇列有讀許可權的程序則可以從訊息佇列中讀走訊息。include include include include include include in...

linux程序間通訊之訊息佇列

訊息佇列 使用訊息佇列的好處 可以給訊息附加特定的訊息型別。訊息佇列用於同一臺計算機的程序間的通訊。include include key t ftok const char pathname,int proj id 該函式根據檔名生成乙個id 系統建立ipc 通訊 訊息佇列 訊號量和共享記憶體 時...

Linux程序間通訊之訊息佇列

實現功能 編寫程式sender,它建立乙個訊息佇列 然後,迴圈等待使用者通過終端輸入一串字元,將這串字元通過訊息佇列傳送給receiver,直到使用者輸入 bye 為止 最後,它向receiver程序傳送訊息 end 並且等待receiver的應答,等到應答訊息後,將接收到的應答資訊顯示在終端螢幕上...