消息队列
可以发送和接收多个消息,这些消息可以在消息队列中进行缓存(没取走,还在消息队列中保存)
注意:它不像管道那样是基于字节流,而是##基于消息##。
也就是说,消息队列不一定是先进先出了。
如何使用消息队列(和使用共享内存类似)
a.创建消息队列 msgget()
b.发送消息 msgsnd()
c.接收消息 msgrcv()
d.删除消息队列
创建消息msgget
msgget(key_t key, int msgflg); //message get
1) int msgid = msgget(IPC_PRIVATE, 0666); //父子进程
2) int msgid = msgget(44444, 0666 | IPC_CREAT); //不相关的进程
发送消息msgsnd
struct msgbuf a = {2,"hello"};
msgsnd(msgid, &a, sizeof(a)-sizeof(long), 0);
发送方式选项 0 阻塞(如果消息队列满,会等)
IPC_NOWAIT 不阻塞
消息队列满或个数满时会返回-1,并且置EAGAIN错误
消息队列的容量问题
消息队列中,每个消息的正文的最大长度为8192.(单个消息)
一个消息队列中的所有消息最多占16384字节。超过这个值后,发送函数msgsnd阻塞。
最多可以创建256个消息队列。
接收消息msgrcv
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
前三个参数同msgsnd函数
第四个参数:
msgtyp 0 接收消息队列中第一个消息(不关心类型)
>0 接收消息队列中类型值为msgtyp的第一个消息
第五个参数:
接收方式选项 0 阻塞(如果消息队列空,会等)
IPC_NOWAIT 不阻塞
删除消息队列msgctl
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
参数:
1) msgid
2) int cmd
IPC_STAT //获取消息队列属性
IPC_SET //设置消息队列属性的
IPC_RMID //用于删除消息队列对象
3) struct msqid_ds *buf // 消息队列缓存区
ipcs -q //显示消息队列信息
ipcrm -q 11111 //11111代表的是消息队列的ID 删除消息队列
注意:
//struct msgbuf data = {atoi(argv[1]),(char *)argv[2]}; --->错误的
编译没错,结果错 ----数组名不能更改地址
参考如下的方式:
struct msgbuf data;
data.msgtype = atoi(argv[1]);
strcpy(data.msgtext,argv[2]);