第二十六章 system v消息队列(二)

时间:2023-03-08 19:39:20
第二十六章 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;
}