由於最近的工作中需要用到消息隊列,順帶花時間整理了一下。
C語言消息隊列,有三種,一種是System V ipc,第二種的是posix ipc,第三種是自己用代碼實現的消息隊列。
System V ipc 和Posix ipc 也叫進程間通信。(IPC的全稱是Inter-process Comminication,就是進程間通信)。
進程間通信分為三個內容,分別是:消息隊列、信號量和共享內存。
System V IPC也分為以下三種類型:
System V 消息隊列
System V 信號量
System V 共享內存區
System V IPC 三種類型
本文將主要介紹System V 消息隊列
在System V IPC中,System v ipc中有一個重要的類型是key_t,在msget、semget、shmget函數操作中都需要利用這個類型是參數。
key_t的值由函數ftok來生成,函數ftok把一個[已存在的路徑名,pathname]和一個[整數標識符,id]轉換稱一個key_t值, 稱為IPC鍵。
key_t ftok(const char *pathname, int proj_id);
System V 消息隊列
消息隊列函數由msgget、msgctl、msgsnd、msgrcv四個函數組成。
1.msgget函數原型

msgget函數原型
如果用msgget創建了一個新的消息隊列對象時,則msqid_ds結構成員變數的值設置如下:
msg_qnum、msg_lspid、msg_lrpid、 msg_stime、msg_rtime設置為0。
msg_ctime設置為當前時間。
msg_qbytes設成系統的限制值。
msgflg的讀寫許可權寫入msg_perm.mode中。
msg_perm結構的uid和cuid成員被設置成當前進程的有效用戶ID,gid和cuid成員被設置成當前進程的有效組ID。
2.msgctl函數原型

msgctl函數原型
3.msgsnd函數原型

msgsnd函數原型
msgsnd()為阻塞函數,當消息隊列容量滿或消息個數滿會阻塞。消息隊列已被刪除,則返回EIDRM錯誤;被信號中斷返回E_INTR錯誤。
如果設置IPC_NOWAIT消息隊列滿或個數滿時會返回-1,並且置EAGAIN錯誤。
msgsnd()解除阻塞的條件有以下三個條件:
① 不滿足消息隊列滿或個數滿兩個條件,即消息隊列中有容納該消息的空間。
② msqid代表的消息隊列被刪除。
③ 調用msgsnd函數的進程被信號中斷。
4.msgrcv函數原型

msgrcv函數原型
msgrcv()解除阻塞的條件有以下三個:
① 消息隊列中有了滿足條件的消息。
② msqid代表的消息隊列被刪除。
③ 調用msgrcv()的進程被信號中斷。
消息隊列使用程序範例
msgrcv.c
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>
struct msgbuf
{
long type;
int groupid;
int appid;
char buf[1024];
};
int main()
{
int msgid;
msgid=msgget(0x1000,IPC_CREAT | 0777);
struct msgbuf mb;
msgrcv(msgid,&mb,sizeof(struct msgbuf)-sizeof(long),1,0);
printf("type: %dtgroupid: %dtappid: %dn", mb.type,mb.groupid, mb.appid);
puts(mb.buf);
}msgsnd.c
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>
struct msgbuf
{
long type;//類型
int groupid;
int appid;
char buf[1024];
};
int main()
{
int msgid;
msgid=msgget(0x1000,IPC_CREAT | 0777);
struct msgbuf mb={1,1,1,"hello world"};
int ret;
ret=msgsnd(msgid,&mb,sizeof(struct msgbuf)-sizeof(long),0);
//這裡的長度不包括類型的大小
}測試

在運行./msgsnd程序後,使用ipcs命令,可查看到消息隊列的狀態信息。如下圖,顯示有一條消息。
分步執行和查看消息隊列信息
在後台執行./msgsnd &。
發送消息
ipcs查看Message Queues信息。
查看ipcs
執行./msgrcv,接收消息隊列信息。
接收消息
ipcs查看Message Queues信息。消息已被接收。
查看ipcs
最後是對POSIX和System V的一個起源介紹
POSIX
POSIX(Portable Operating System Interface for Computing Systems)是由IEEE 和ISO/IEC 開發的一簇標準。該標準是基於現有的UNIX 實踐和經驗,描述了操作系統的調用服務介面,用於保證編製的應用程序可以在源代碼一級上在多種操作系統上移植運行。它是在1980 年早期一個UNIX 用戶組(usr/group)的早期工作的基礎上取得的。該UNIX 用戶組原來試圖將AT&T 的系統V 和Berkeley CSRG的BSD 系統的調用介面之間的區別重新調和集成,從而於1984 年產生了/usr/group 標準。1985 年,IEEE操作系統技術委員會標準小組委員會(TCOS-SS)開始在ANSI 的支持下責成IEEE 標準委員會制定有關程序源代碼可移植性操作系統服務介面正式標準。到了1986 年4 月,IEEE 就制定出了試用標準。第一個正式標準是在1988 年9 月份批准的(IEEE 1003.1-1988),也既以後經常提到的POSIX.1 標準。
System V
System V, 曾經也被稱為 AT&T System V,是Unix操作系統眾多版本中的一支。它初由 AT&T 開發,在1983年第一次發布。一共發行了4個 System V 的主要版本:版本1、2、3 和 4。System V Release 4,或者稱為SVR4,是成功的版本,成為一些UNIX共同特性的源頭,例如 」SysV 初始化腳本「 (/etc/init.d),用來控制系統啟動和關閉,System V Interface Definition (SVID) 是一個System V 如何工作的標準定義。
AT&T 出售運行System V的專有硬體,但許多(或許是大多數)客戶在其上運行一個轉售的版本,這個版本基於 AT&T 的實現說明。流行的SysV 衍生版本包括 Dell SVR4 和 Bull SVR4。當今廣泛使用的 System V 版本是 SCO OpenServer,基於 System V Release 3,以及SUN Solaris 和 SCO UnixWare,都基於 System V Release 4。
System V 是 AT&T 的第一個商業UNIX版本(UNIX System III)的加強。傳統上,System V 被看作是兩種UNIX”風味”之一(另一個是 BSD)。然而,隨著一些並不基於這兩者代碼的UNIX實現的出現,例如 Linux 和 QNX, 這一歸納不再準確,但不論如何,像POSIX這樣的標準化努力一直在試圖減少各種實現之間的不同。
就先到這裡,後面再講一下Posix消息隊列和自己用代碼實現的消息隊列。
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/202706.html
微信掃一掃
支付寶掃一掃