參數:
key:可以認為是一個端口號,也可以由函數ftok生成。
msgflg:IPC_CREAT值,若沒有該隊列,則創建一個並返回新標識符;若已存在,則返回原標識符。
IPC_EXCL值,若沒有該隊列,則返回-1;若已存在,則返回0。
msgrcv從隊列中取用消息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
msgsnd將數據放到消息隊列中:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
參數:
msqid:消息隊列的標識碼
msgp:指向消息緩沖區的指針,此位置用來暫時存儲發送和接收的消息,是一個用戶可定義的通用結構,形態如下:
msgsz:消息的大小。msgtyp:從消息隊列內讀取的消息形態。如果值為零,則表示消息隊列中的所有消息都會被讀取。
msgflg:用來指明核心程序在隊列沒有數據的情況下所應采取的行動。如果msgflg和常數IPC_NOWAIT合用,則在msgsnd()執行時若是消息隊列已滿,則msgsnd()將不會阻塞,而會立即返回-1,如果執行的是msgrcv(),則在消息隊列呈空時,不做等待馬上返回-1,並設定錯誤碼為ENOMSG。當msgflg為0時,msgsnd()及msgrcv()在隊列呈滿或呈空的情形時,采取阻塞等待的處理模式。
參數:msgctl 系統調用對 msgqid 標識的消息隊列執行 cmd 操作,系統定義了 3 種 cmd 操作: IPC_STAT , IPC_SET , IPC_RMID
IPC_STAT : 該命令用來獲取消息隊列對應的 msqid_ds 數據結構,並將其保存到 buf 指定的地址空間。
IPC_SET : 該命令用來設置消息隊列的屬性,要設置的屬性存儲在buf中。
IPC_RMID : 從內核中刪除 msqid 標識的消息隊列。
/*send.c*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#define MSGKEY 1024
struct msgstru
{
long msgtype;
char msgtext[2048];
};
main()
{
struct msgstru msgs;
int msg_type;
char str[256];
int ret_value;
int msqid;
msqid=msgget(MSGKEY,IPC_EXCL); /*檢查消息隊列是否存在*/
if(msqid < 0){
msqid = msgget(MSGKEY,IPC_CREAT|0666);/*創建消息隊列*/
if(msqid <0){
printf("failed to create msq | errno=%d [%s]\n",errno,strerror(errno));
exit(-1);
}
}
while (1){
printf("input message type(end:0):");
scanf("%d",&msg_type);
if (msg_type == 0)
break;
printf("input message to be sent:");
scanf ("%s",str);
msgs.msgtype = msg_type;
strcpy(msgs.msgtext, str);
/* 發送消息隊列 */
ret_value = msgsnd(msqid,&msgs,sizeof(struct msgstru),IPC_NOWAIT);
if ( ret_value < 0 ) {
printf("msgsnd() write msg failed,errno=%d[%s]\n",errno,strerror(errno));
exit(-1);
}
}
msgctl(msqid,IPC_RMID,0); //刪除消息隊列
}
消息接收端 receive.c
/*receive.c */
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#define MSGKEY 1024
struct msgstru
{
long msgtype;
char msgtext[2048];
};
/*子進程,監聽消息隊列*/
void childproc(){
struct msgstru msgs;
int msgid,ret_value;
char str[512];
while(1){
msgid = msgget(MSGKEY,IPC_EXCL );/*檢查消息隊列是否存在 */
if(msgid < 0){
printf("msq not existed! errno=%d [%s]\n",errno,strerror(errno));
sleep(2);
continue;
}
/*接收消息隊列*/
ret_value = msgrcv(msgid,&msgs,sizeof(struct msgstru),0,0);
printf("text=[%s] pid=[%d]\n",msgs.msgtext,getpid());
}
return;
}
void main()
{
int i,cpid;
/* create 5 child process */
for (i=0;i<5;i++){
cpid = fork();
if (cpid < 0)
printf("fork failed\n");
else if (cpid ==0) /*child process*/
childproc();
}
}