第二十六章 system v消息队列(二)
msgsnd
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
作用:
把一条消息添加到消息队列中
参数:
msqid : 由msgget函数返回的消息队列标识
msgp :是一个指针,指针指向准备发送的消息
msgsz :是msgp指向的消息长度,这个长度不含保存消息类型的那个long int长整型
msgflg :控制着当前消息队列或到达系统上限时将要发生的事情
IPC_NOWAIT表示队列满不等待,返回EAGAIN错误
0 表示队列满阻塞
返回值:
成功 : 0
失败 : -1
msgbuf
消息结构在两方面受制约:
- 它必须小于系统规定的上限值(MSGMAX)
- 它必须以一个long int长整数开始,接收者函数将利用这个长整数确定消息的类型
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
int main(int argc, char const *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");
printf("msget success, msgid=%d\n!",msgid);
struct msgbuf* ptr;
ptr = (struct msgbuf*)malloc(sizeof(long)+len);
ptr->mtype = type;
// =MSGMNB 阻塞
// >MSGMNB Invalid argument
// if(msgsnd(msgid, ptr, len, 0) < 0)
// =MSGMNB Resource temporarily unavailable
// >MSGMNB Invalid argument
if(msgsnd(msgid, ptr, len, IPC_NOWAIT) < 0)
ERR_EXIT("msgsnd");
free(ptr);
return 0;
}
msgrcv
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
作用:
从消息队列接受消息
参数:
msqid : 由msgget函数返回的消息队列标识
msgp :是一个指针,指针指向准备接收的消息
msgsz :是msgp指向的消息长度,这个长度不含保存消息类型的那个long int长整型
msgtyp :它可以实现接收优先级的简单形式
=0 : 返回队列第一条消息
>0 : 返回队列第一条类型等于msgtype的消息
<0 : 返回队列第一条类型小于等于msgtype绝对值的消息
>0 && msgflg=MSC_EXCEPT 接收类型不等于msgtype的第一条消息
msgflg :控制着队列中没有相应类型的消息可提供接收时将要发生的事
IPC_NOWAIT表示队列满不等待,返回EAGAIN错误
MSG_NOERROR 消息大小超过msgsz时被截断
0 表示队列满阻塞
返回值:
成功 : 返回实际放到接收缓冲区里的字符个数
失败 : -1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
#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(opt == -1)
break;
switch (opt)
{
case 'n':
flag |= IPC_NOWAIT;
break;
case 't':
type = atoi(optarg);
break;
}
}
int msgid;
msgid = msgget(1234,0);
if(msgid == -1)
ERR_EXIT("msgget");
printf("msget success, msgid=%d\n",msgid);
struct msgbuf* ptr;
ptr = (struct msgbuf*)malloc(sizeof(long) + MSGMAX);
ptr->mtype = type;
int nRec = 0;
if( (nRec = msgrcv(msgid, ptr, MSGMAX, type, flag)) < 0)
ERR_EXIT("msgsnd");
printf("read %d bytes type = %ld\n", nRec, ptr->mtype);
free(ptr);
return 0;
}