6.1 概述
struct msqid_ds "头结点" -> 表示一个“消息队列”
{
struct ipc_perm msg_perm;
struct msg *msg_first;
struct msg *msg_last;
msglen_t msg_cbytes;
msgqnum_t msg_qnum;
msglen_t msq_qbytes;
pid_t msg_lspid;
pid_t msg_lrpid;
time_t msg_stime;
time_t msg_rtime;
time_t msg_ctime;
};
6.2 msgget 函数
- msgget()用于创建一个新的消息队列或访问一个已存在的消息队列
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
- 返回值是一个整数标识符,用来代指队列
- key可以是ftok()的返回值,也可以是常值IPC_PRIVATE(保证产生一个唯一的对象)
6.3 msgsnd函数
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
- msqis是msgget返回的标识符
- ptr是一个结构指针,定义在
struct msgbuf{
long mtype;
char mtext[];
};
- msgflg: 发送标志:
- (1) 0 阻塞模式(默认)
- (2) IPC_NOWAIT 非阻塞模式,失败返回EAGAIN错误
- msgsz: 消息内容长度,上述结构体数组mtext的实际大小
- 成功返回0,失败返回-1,同时errno被设置
6.4 msgrcv()函数
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
- msqid: 消息队列id
- msgp:指向消息结构(就上述自定义的结构体),用来保存读取的消息。
- msgsz: msgp指向的消息结构体,最多可以保存多少字节的消息。
- msgtyp: 您想要读取的消息类型 (0为任意类型)
- msgflg:
- (1) 0 阻塞模式
- (2) IPC_NOWAIT -> 非阻塞模式
- 返回值:
- 成功返回实际读入缓冲区中数据的字节数,失败返回-1, 同时errno被设置。
6.5 msgctl()函数
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
- 该函数提供三个命令
- IPC_RMID :删除由msqid指定的消息队列
- IPC_SET :设置结构体中相应成员
- IPC_STAT :返回所指定消息队列对应当前msqid_ds的结构
6.7 客户服务器例子
#include "unpipc.h"
#define MAXMESGDATA (PIPE_BUF - 2*sizeof(long))
#define MESGHDRSIZE (sizeof(struct mymesg) - MAXMESGDATA)
struct mymesg {
long mesg_len;
long mesg_type;
char mesg_data[MAXMESGDATA];
};
ssize_t mesg_send(int, struct mymesg *);
void Mesg_send(int, struct mymesg *);
ssize_t mesg_recv(int, struct mymesg *);
ssize_t Mesg_recv(int, struct mymesg *);
#include "svmsg.h"
void server(int, int);
int
main(int argc, char **argv)
{
int readid, writeid;
readid = Msgget(MQ_KEY1, SVMSG_MODE | IPC_CREAT);
writeid = Msgget(MQ_KEY2, SVMSG_MODE | IPC_CREAT);
server(readid, writeid);
exit(0);
}
#include "svmsg.h"
void client(int, int);
int
main(int argc, char **argv)
{
int readid, writeid;
writeid = Msgget(MQ_KEY1, 0);
readid = Msgget(MQ_KEY2, 0);
client(readid, writeid);
Msgctl(readid, IPC_RMID, NULL);
Msgctl(writeid, IPC_RMID, NULL);
exit(0);
}
#include "mesg.h"
ssize_t
mesg_send(int id, struct mymesg *mptr)
{
return(msgsnd(id, &(mptr->mesg_type), mptr->mesg_len, 0));
}
void
Mesg_send(int id, struct mymesg *mptr)
{
ssize_t n;
if ( (n = msgsnd(id, &(mptr->mesg_type), mptr->mesg_len, 0)) == -1)
err_sys("mesg_send error");
}
#include "mesg.h"
ssize_t
mesg_recv(int id, struct mymesg *mptr)
{
ssize_t n;
n = msgrcv(id, &(mptr->mesg_type), MAXMESGDATA, mptr->mesg_type, 0);
mptr->mesg_len = n;
return(n);
}
ssize_t
Mesg_recv(int id, struct mymesg *mptr)
{
ssize_t n;
if ( (n = mesg_recv(id, mptr)) == -1)
err_sys("mesg_recv error");
return(n);
}