进程通信之消息队列
消息队列是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。
消息队列允许一个或者多个进程往里面写消息,但是只允许一个进程读消息,一个消息被读取之后会自动删除。
//打开或者创建消息队列
#include <sys/msg.h>
int msgget(key_t key, int flag);
//成功返回消息队列的标识ID,失败返回-1
//参数:
//key: 用户指定消息队列键值,键值在用户空间是唯一,标识是全局唯一。
//flag:
//消息队列的权限,IPC_CREAT、IPC_EXCL
//如果key值为0,则查不到消息队列
#include <sys/msg.h>
int msgctl(int msgid, int cmd, struct msqid_ds *buf);
//return:成功返回0,出错返回-1
/*
msgid:消息队列ID;
cmd:消息队列控制命令:
IPC_STAT:获取消息队列的属性,取此队列的msqid_ds结构,并将其存放在buf指向的结构中;
IPC_SET:设置属性,按由buf指向的结构中的值,设置与此队列相关的结构中的字段;
IPC_RMID:删除队列,从系统中删除消息队列上的所有数据。
buf:消息队列属性指针。
*/
#include <sys/msg.h>
int msgsnd(int msgqid, const void *ptr, size_t nbytes, int flag);
//return:成功返回0,出错返回-1
/*
msgqid:消息队列ID;
ptr:通用指针,指向了想要发送的消息类型指针,其中的类型需要用户自己定义:
struct mymessage
{
long mtype; positive message type
char mtext[512]; message data,of length nbytes
};
nbytes:指定消息的大小,不包括mtype的大小,即只包含数据大小而不包含数据类型大小;
flag:标志参数,可以指定为阻塞和非阻塞。
0:阻塞;
IPC_NOWAIT:非阻塞标志。
*/
当消息队列已满,或者是队列中的消息总数等于系统限制值,或队列中的字节总数等于系统限制值时:
若指定IPC_NOWAIT的状态下:
msgsnd()函数会立即出错返回EAGAIN。
若指定0的状态下:
进程阻塞直到有空间可以容纳要发送的消息;
或从系统中删除了此队列;
或捕捉到一个信号,并从信号处理程序返回。
#include <sys/msg.h>
ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);
//return:成功返回消息的数据部分长度,出错返回-1
/*
msqid:消息队列ID;
ptr:指向存放消息的缓存;
nbytes:消息缓存的大小,不包含mtype的大小。
nbytes = sizeof (struct mymessage) - sizeof(long)
type:消息类型;
type == 0:获得消息队列中的第一个消息;
type > 0:获得消息队列中类型为type的第一个消息;
type < 0:获得消息队列中小于或等于type绝对值(即最小的)消息;
flag:0 或者 IPC_NOWAIT。
*/