前言:數據結構
消息隊列就是一個消息的鏈表。能夠把消息看做一個記錄,具備特定的格式以及特定的優先級。對消息隊列有寫權限的進程能夠向其中按照必定的規則添加新消息;對消息隊列有讀權限的進程則能夠從消息隊列中讀走消息函數
函數:spa
1.建立新消息隊列或取得已存在消息隊列指針
原型:code
1 int msgget(key_t key, int msgflg);
參數:blog
key:能夠認爲是一個端口號,也能夠由函數ftok生成。隊列
msgflg:IPC_CREAT值,若沒有該隊列,則建立一個並返回新標識符;若已存在,則返回原標識符。進程
IPC_EXCL值,若沒有該隊列,則返回-1;若已存在,則返回0。ip
2.向隊列讀/寫消息get
原型:
msgrcv從隊列中取用消息:
1 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
msgsnd將數據放到消息隊列中:
1 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
參數:
msqid:消息隊列的標識碼
msgp:指向消息緩衝區的指針,此位置用來暫時存儲發送和接收的消息,是一個用戶可定義的通用結構,形態以下:
1 struct msgstru{ 2 long mtype; //大於0 3 char mtext[512]; 4 };
msgsz:消息的大小。
msgtyp:從消息隊列內讀取的消息形態。若是值爲零,則表示消息隊列中的全部消息都會被讀取。
msgflg:用來指明核心程序在隊列沒有數據的狀況下所應採起的行動。若是msgflg和常數IPC_NOWAIT合用,則在msgsnd()執行時如果消息隊列已滿,則msgsnd()將不會阻塞,而會當即返回-1,若是執行的是msgrcv(),則在消息隊列呈空時,不作等待立刻返回-1,並設定錯誤碼爲ENOMSG。當msgflg爲0時,msgsnd()及msgrcv()在隊列呈滿或呈空的情形時,採起阻塞等待的處理模式。
3.設置消息隊列屬性
原型:
int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );
參數:msgctl 系統調用對 msgqid 標識的消息隊列執行 cmd 操做,系統定義了 3 種 cmd 操做: IPC_STAT , IPC_SET , IPC_RMID
IPC_STAT : 該命令用來獲取消息隊列對應的 msqid_ds 數據結構,並將其保存到 buf 指定的地址空間。
IPC_SET : 該命令用來設置消息隊列的屬性,要設置的屬性存儲在buf中。
IPC_RMID : 從內核中刪除 msqid 標識的消息隊列。
實例:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/types.h> 4 #include <sys/ipc.h> 5 #include <sys/msg.h> 6 #include <errno.h> 7 8 #define MSGKEY 1234 9 10 int main(int agrc, char* agrv[]) 11 { 12 struct msgstru 13 { 14 long msgtype; 15 char msgtext[2048]; 16 } msgs; 17 int msg_type; 18 char str[256]; 19 int ret_value; 20 21 int msqid=msgget(MSGKEY,IPC_EXCL); /*檢查消息隊列是否存在*/ 22 if(msqid < 0) 23 { 24 msqid = msgget(MSGKEY,IPC_CREAT|0666);/*建立消息隊列*/ 25 if(msqid <0) 26 { 27 perror("msgget"); 28 exit(EXIT_FAILURE); 29 } 30 } 31 32 pid_t pid = fork(); 33 if (pid < 0) 34 exit(EXIT_FAILURE); 35 else if (pid > 0) 36 { 37 while(1) 38 { 39 msqid = msgget(MSGKEY,IPC_EXCL );/*檢查消息隊列是否存在 */ 40 if (msqid < 0) 41 { 42 perror("msgget"); 43 break; 44 } 45 /*接收消息隊列*/ 46 ret_value = msgrcv(msqid,&msgs,sizeof(struct msgstru),0,0); 47 printf("text=[%s] pid=[%d]\n",msgs.msgtext,getpid()); 48 } 49 } 50 else 51 { 52 while (1) 53 { 54 printf("input message type(end:0):"); 55 scanf("%d",&msg_type); 56 if (msg_type == 0) 57 break; 58 printf("input message to be sent:"); 59 scanf ("%s",str); 60 msgs.msgtype = msg_type; 61 strcpy(msgs.msgtext, str); 62 /* 發送消息隊列 */ 63 ret_value = msgsnd(msqid,&msgs,sizeof(struct msgstru),IPC_NOWAIT); 64 if ( ret_value < 0 ) 65 { 66 perror("msgsend"); 67 exit(EXIT_FAILURE); 68 } 69 } 70 } 71 msgctl(msqid,IPC_RMID,0); //刪除消息隊列 72 return 0; 73 }
總結:各類通訊方式大同小易,原理都差很少,都是由系統提供支持的通訊方式。