1.msgsnd函数
(1)功能:把一条消息添加到消息队列中
(2)原型:intmsgsnd(int msqid, const void* msgp. size_t msgsz, int msgflg);
(3)参数:msgqid:由msgget函数返回的消息队列标识码
msgp:是一个指针,指针指向准备发送的消息
msgsz:是msgp指向的消息长度,这个长度不含保存消息类型的那个long int长整型
msgflg:控制着当前消息队列满或到达系统上限时将要发生的事情
(4)返回值:成功返回0,;失败返回-1
(5)msgflg=IPC_NOWAIT表示队列满不等待,返回EAGAIN错误
(6)消息结构在两方面收到制约。首先它必须小于系统规定的上限值;其次,它必须以一个long int长整数开始,接收者函数将利用这个长整数确定消息的类型
(7)消息结构参考形式如下:
struct msgbuf {
long mtype;
char mtext[1];
};
2.msgrcv函数
(1)功能:是从一个消息队列接收消息
(2)原型:ssize_t msgrcv(int msgqid, void*msgp, size_t msgsz, long msgtyp, int msgflg);
(3)参数:msgid:由msgget函数返回的消息队列标识码
msgp:是一个指针,指针指向准备接收的消息
msgsz:是msgp指向的消息长度,这个长度不含保存消息类型的那个long int长整型
msgtype:它可以实现接收优先级的简单形式
msgflg:控制着队列中没有相应类型的消息可供接收时将要发生的事
(4)返回值:成功返回实际放到接收缓冲区里去的字符个数,失败返回-1
(5)msgtype=0返回队列第一条消息
(6)msgtyp>0返回队列第一条类型等于msgtype的消息
(7)msgtyp<0返回队列第一条类型小于等于msgtype绝对值的消息(消息类型最小的先接收)
(8)msgflg=IPC_NOWAIT,队列没有可读消息不等待,返回ENOMSG错误
(9)msgtyp=MSG_NOERROR,消息大小超过msgsz是被截断
(10)msgtyp>0且msgflg=MSG_EXCEPT,接收类型不等于msgtype的第一条消息
3.示例
msg_send.cpp
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
struct MSG {
long mtype;
char mtext[1];
};
int main(int argc, char* argv[]) {
if(argc != 3) {
fprintf(stderr, "Usage: %s <bytes> <type>\n", argv[0]);
exit(EXIT_FAILURE);
}
int len = atoi(argv[1]);
int type = atoi(argv[2]);
int msgid;
msgid = msgget(1234, 0); //按照原来创造的权限打开
if(msgid == -1)
ERR_EXIT("msgget");
struct MSG* ptr;
ptr = (struct MSG*)malloc(sizeof(long)+len);
ptr->mtype = type;
if(msgsnd(msgid, ptr, len, 0) <0)
ERR_EXIT("msgsnd");
return 0;
}
msg_recv.cpp
./recv -n -t 2
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
struct MSG {
long mtype;
char mtext[1];
};
#define MSGMAX 8192
int main(int argc, char* argv[]) {
int flag = 0;
int type = 0;
int opt;
while(1) {
opt = getopt(argc, argv, "nt:");
if(opt == '?')
exit(EXIT_FAILURE);
if(-1 == opt)
break;
switch(opt) {
case 'n':
flag |= IPC_NOWAIT;
break;
case 't':
//int n = atoi(optarg);
//printf("n=%d\n", n);
type = atoi(optarg);
break;
}
}
int msgid;
msgid = msgget(1234, 0); //按照原来创造的权限打开
if(msgid == -1)
ERR_EXIT("msgget");
struct MSG* ptr;
ptr = (struct MSG*)malloc(sizeof(long)+MSGMAX);
ptr->mtype = type;
int n = 0;
if((n=msgrcv(msgid, ptr, MSGMAX, type, flag)) < 0)
ERR_EXIT("msgsnd");
printf("read %d bytes type=%ld\n", n, ptr->mtype);
return 0;
}