通过ipcs
可以查看消息队列
新增头文件
消息队列中消息的新增和删除是对等的,内部维护一个链表,插入一个消息,删除一个消息
管道中的消息是不对等的,可以一个放入一个"hello",再放入一个"hello",最后一次取出
对于多机之间采用消息队列,而不采用管道
进程结束,消息队列依然存在
消息队列中存放的消息类型为自己手动设置的,每个消息为消息队列中的一个结点
消息队列为空时再次读取会卡住
创建消息队列
5 //创建消息队列
6 int msgid=msgget(1000,IPC_CREAT|0600);
7 ERROR_CHECK(msgid,-1,"msgget");
发送消息
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//第二个参数是一个结构体 const void *msgp
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
//必须要重写这个结构体,第一个参数不能改
//size_t msgsz 为消息体大小(m.mtext的大小)
14 struct msgbuf m;
15 m.mtype=1;//消息类型为1
16 strcpy(m.mtext,"hello");
17 int ret;
18 ret=msgsnd(msgid,&m,strlen(m.mtext),0);
19 ERROR_CHECK(ret,-1,"msgsnd");
------ Message Queues --------
key msqid owner perms used-bytes messages
0x000003e8 0 wenrou 600 5 1
1 #include
2
✗ 3 struct msgbuf{
4 long mtype;
5 char mtext[128];
6 };
7
8
✹ 9 int main(int argc,char*argv[])
10 {
11 //创建消息队列
12 int msgid=msgget(1000,IPC_CREAT|0600);
13 ERROR_CHECK(msgid,-1,"msgget");
14 struct msgbuf m;
15 m.mtype=1;//消息类型为1
16 strcpy(m.mtext,"hello");
17 int ret;
18 ret=msgsnd(msgid,&m,strlen(m.mtext),0);
19 ERROR_CHECK(ret,-1,"msgsnd");
20
21 return 0;
22 }
//若发送的消息类型为整数,不能再使用strcpy
//结构体中的mtext仍定义为字符数组
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[128]; /* message data */
};
int i=100;
//除了字符串,其他类型都要用 memcpy
memcpy(m.mtext,&i,sizeof(i));
int ret;
ret=msgsnd(msgid,&m,sizeof(i),0);
ERROR_CHECK(ret,-1,"msgsnd");
接收消息
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
long msgtyp //优先去读取的消息队列中的消息类型,若该参数设置为0,则按照消息队列顺序读取
1 #include
2
✗ 3 struct msgbuf{
4 long mtype;
5 char mtext[128];
6 };
7
8
✹ 9 int main(int argc,char*argv[])
10 {
11 //创建消息队列
12 int msgid=msgget(1000,IPC_CREAT|0600);
13 ERROR_CHECK(msgid,-1,"msgget");
14 struct msgbuf m={0,{0}};//两个成员
15 //读取消息队列
16 int ret;
17 ret=msgrcv(msgid,&m,sizeof(m.mtext),0,0);
18 ERROR_CHECK(ret,-1,"msgrcv");
19 printf("m.mtype=%ld,m.mtext=%s\n",m.mtype,m.mtext);
20 return 0;
21 }
//接收整数
memcpy(&i,m.mtext,sizeof(i));
//或者这样写,先强制类型转换,再解引用
i = *(int *)m.mtext;
删除消息队列
5 int msgid=msgget(1000,IPC_CREAT|0600);
6 ERROR_CHECK(msgid,-1,"msgget");
7 int ret;
8 ret=msgctl(msgid,IPC_RMID,NULL);
9 ERROR_CHECK(ret,-1,"msgctl");
10 return 0;
使用命令删除消息队列
ipcrm -q msqid