Linux基礎入門 程序間通訊 訊息佇列

2021-10-01 22:35:01 字數 3803 閱讀 9723

system v提供的ipc機制主要有訊息佇列,訊號量和共享記憶體3種機制。和檔案一樣,ipc在使用前必須先建立,每種ipc都有特定的生產者,所有者和訪問許可權。使用ipcs命令可以檢視當前系統正在使用的ipc工具:

[root@localhost swz] # ipcs

------- shared memory segments --------- //共享記憶體

key shmid ower perms bytes nattch status

------- semaphore arrays --------- //訊號量

key shmid ower perms nsems

------- message queues ----------- //訊息佇列

key shmid ower perms used-bytes messages

由以上可以看出,乙個ipc工具至少包含key值,id值,擁有者,許可權和使用的大小等關鍵資訊。如果需要手動刪除某個ipc機制,可以使用ipcrm命令。

linux系統為每個ipc機制都分配了唯一的id,所有針對該ipc機制的操作都使用該id值。因此,通訊的雙方都需要通過某個方法來獲取id值。建立者根據建立函式的返回值可以獲取該值,但另乙個程序如何實現呢?linux兩個程序不能隨意訪問對方的空間(乙個特殊是子程序可以繼承父程序的資料,實現父程序向子程序的單向傳遞),也就不能夠直接獲取到這一id值。

為解決這一問題,ipc在實現時約定使用key值做為引數建立,如果在建立時使用相同的key值將得到同乙個ipc物件的id值(即一方建立,另一方獲取的是id),這樣就保證了雙方可以獲取用於傳遞資料的ipc機制id值。key值為乙個32位的整型資料。

但如果所有的程式使用固定的key建立這些ipc機制則有違軟體設計思想,因此,為了盡可能與系統資訊的載體(檔案)關聯,linux提供函式ftok()來建立key值,在此函式的引數中,需要特定檔案作為引數。此函式宣告如下:

extern key_t ftok(__const char *__pathname, int __proj_id);
3.1 訊息佇列模型

訊息佇列是訊息的鏈式佇列,由msqid_ds和msg結構組成

msgid_ds訊息佇列資料結構:描述整個訊息佇列的屬性,主要包括整個訊息佇列的許可權,擁有者,兩個重要的指標分別指向訊息佇列的第乙個訊息和最後乙個訊息。

msg訊息佇列資料結構:整個訊息佇列的主體,乙個訊息佇列有若干訊息,每個訊息資料結構的基本成員包括訊息型別,訊息大小,訊息內容指標和下乙個訊息資料結構位置。

預設情況下,整個系統中最多允許有16個訊息佇列

每個訊息佇列最大為16384位元組

訊息佇列中的每個訊息最大為8192位元組

3.2 建立訊息佇列

在使用乙個訊息佇列錢,需要使用msgget函式建立該訊息佇列,其函式宣告如下:

extern int msgget(key_t __key, int __msg***);
第1個引數key為由ftok建立的key值

第2個引數msg***的低位用來確定訊息佇列的訪問許可權,其最終許可權為當前程序umask值與設定值perm類似open函式,即最終值為perm&~umask,

// include /usr/include/bit/ipc.h

/* resource get request flags */

#define ipc_creat 00001000 //如果key不存在,則建立,存在,則返回id

#define ipc_excl 00002000 //如果key存在,返回失敗

#define ipc_nowait 00004000 //如果需要等待,則直接返回錯誤

3.3 訊息佇列屬性控制

建立訊息佇列後,可以對該訊息佇列的基本屬性進行控制(修改),控制訊息佇列屬性的函式為msgctl:

extern int msgctl(int __msqid, int __cmd, struct maqid_ds *_buf);
此函式包括3個引數

第1個引數__msqid為訊息佇列的識別符號,該值由msgget函式建立返回值

第2個引數__cmd為執行的控制命令,即要執行的操作,包括以下選項:

//include /usr/include/linux/ipc.h

/* control commands used with semctl,msgctl and shmctl see also specific commands in sem.h,msg.h,shm.h */

#define ipc_rmid 0 //刪除

#define ipc_set 1 //設定ipc_perm引數

#define ipc_stat 2 //獲取ipc_perm引數

#define ipc_info 3 //如ipcs,獲取限制資訊

3.4 傳送資訊到訊息佇列

msgsnd()函式將新的訊息新增到訊息佇列尾端。此函式宣告如下:

//include /usr/include/sys/msg.h

//send message to message queue

extern int msgsnd(int _msqid, _const void *_magp, size_t _msgsz, int _msg***);

此函式引數說明如下:

第1個引數msqid為指定的訊息佇列識別符號(由msgget生成的訊息佇列識別符號),即將訊息新增到哪個訊息佇列中。

第2個引數msgp指向的使用者定義緩衝區,下面是使用者定義緩衝區結構:

//include /usr/include/linux/msg.h

//message buffer for msgsnd and msgrcv calls

struct msgbuf

第3個引數為接受資訊的大小,其資料型別為size_t,即unsigned int 型別,其大小為0到系統對訊息佇列的限制值

第4個引數用來指定在達到系統為訊息佇列所界定是應採取的操作。

如果設定為ipc_nowait,如果需要等待,則不傳送訊息並且呼叫程序立即返回錯誤資訊eagain.

如果為設定ipc_nowait,則阻塞呼叫程序

成功呼叫後,此函式將返回0,否則返回-1,同時將對訊息佇列msqid資料結構的成員執行下列操作。

msg_qnum以1位增量遞增

msg_lspid設定為呼叫程序的程序id

msg_stime設定為當前時間

3.5 從訊息佇列接受資訊

msgrcv用於從佇列中取訊息,其函式宣告如下:

extern int msgrcv(int _msqid, void *_msgp, size_t _msgsz, long int _msgtype,int _msg***);
此函式從msqid指定的訊息佇列中讀取訊息,並將其放置到由msgp指向的記憶體空間中。

第1個引數為讀的物件,即從哪個訊息佇列獲取訊息

第2個引數為乙個臨時訊息資料結構,用來儲存讀取的資訊。其結構如下:

//include /usr/include/linux/msg.h

//message buffer for msgsnd and msgrcv calls

struct msgbuf

《共享記憶體》Linux程序間通訊入門

執行 共享記憶體要想好用,共享的那段記憶體,需要用資料結構和佇列組織起來,加上讀寫索引和資料有效標誌 已讀和未讀 可讀 下面的這個示例 是我初學時的,適合入門和了解使用流程。寫端 include include include include include include include incl...

Linux程序間通訊

程序間通訊 ipc interprocess communication 基本機制 訊號 管道及命名管道 訊息佇列 共享主存 訊號量 套接字。訊號 全稱軟中斷訊號,是在軟體層次上對中斷機制的一種模擬,它也是程序間通訊機制中唯一的非同步通訊機制。linux訊號處理函式可分為訊號安裝函式 訊號傳送函式和...

Linux程序間通訊

謝謝nonoob糾錯 我們在linux訊號基礎中已經說明,訊號可以看作一種粗糙的程序間通訊 ipc,interprocess communication 的方式,用以向程序封閉的記憶體空間傳遞資訊。為了讓程序間傳遞更多的資訊量,我們需要其他的程序間通訊方式。這些程序間通訊方式可以分為兩種 1.管道與...