进程间通信--消息队列

1.消息队列的介绍

image.png


2.消息队列的系统调用

1)msgget
int msgget(key_t key, int msqflg);

msgget()创建或者获取一个消息队列
msgget()成功返回消息队列 ID,失败返回-1
msqflg: IPC_CREAT
2)msgsnd

int msgsnd(int msqid, const void *msqp, size_t msqsz, int msqflg);

msgsnd()发送一条消息;
//参数意义:
msqid:消息队列的id,因为系统中可能有多个消息队列,这id指明往哪个消息队列中添加数据;
msqp:往消息队列中添加的结构体,消息结构为:
struct msgbuf
 {
long mtype; // 消息类型, 必须大于0(或者说>=1),长整型,比如图中的1,2
char mtext[1]; // 消息数据 ,用户自己定义,可以是任何类型;这里存放消息数据
};
msqsz: 指定 mtext 中有效数据的长度//注意仅仅只接收的数据的大小,不包含消息类型的大小;
msqflg:一般设置为 0 可以设置 IPC_NOWAIT//标志位,比如消息队列满了,是阻塞还是失败返回呢?给0代表消息满了自动阻塞,设置 IPC_NOWAIT意思是当整个消息队列满的时候会立即返回(no wait),返回一个失败而已
//返回值
msgsnd()成功返回 0, 失败返回-1
3)msgrcv
ssize_t msgrcv(int msqid, void *msgp, size_t msqsz, long msqtyp, int msqflg);

msgrcv()接收一条消息
msgrcv()成功返回 mtext 中接收到的数据长度, 失败返回-1,
msgp:接收消息的结构体,一般约定好,写入什么,接收什么结构体;
msqsz:接收消息的大小,大于等于发送的消息大小,一般和发送的消息大小一样.
msqtyp: 指定接收的消息类型(图中的1和2),类型可以为 0,为0表示不区分消息类型,按顺位接收消息;
msqflg: 一般设置为 0 可以设置 IPC_NOWAIT
//设置为IPC_NOWAIT,意思是当整个消息队列空的时候会立即返回(no wait),返回一个失败而已
//设置为0,意思是当整个消息队列空的时候会阻塞
4)msgctl
int msgctl(int msqid, int cmd, struct msqid_ds *buf); 

msgctl()控制消息队列,也就是对消息队列做一个控制,可以设置消息队列,也可以移除消息队列;
msgctl()成功返回 0,失败返回-1
cmd: IPC_RMID
buf:设置或者获取消息队列需要的一个结构体,如果删除就直接给一个NULL;

//当创建一个消息队列的时候,只要不移除这个消息队列,它就会一直在,除非重启系统.
//或者人为删除:ipcrm -q  id

3.消息队列的使用---代码演示

进程 a 发送一条消息,进程 b 读取消息。

 //a.c
1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <assert.h>
  5 #include <string.h>
  6 #include <sys/msg.h>
  7 
  8 struct mess
  9 {
 10     long type;
 11     char buff[128];
 12 };
 13 
 14 int main()
 15 {
 16     int msgid=msgget((key_t)1234,IPC_CREAT|0600);
 17     assert(msgid!=-1);
 18 
 19     struct mess dt;
 20     dt.type=1;
 21     strcpy(dt.buff,"hello1");
 22 
 23     msgsnd(msgid,&dt,128,0);
 24 
 25     exit(0);
 26 }
  
    
    
 //b.c   
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <assert.h>
  5 #include <string.h>
  6 #include <sys/msg.h>
  7 
  8 struct mess
  9 {
 10     long type;
 11     char buff[128];
 12 };
 13 
 14 int main()
 15 {
 16     int msgid=msgget((key_t)1234,IPC_CREAT|0600);
 17     assert(msgid!=-1);
 18 
 19     struct mess dt;
 20 
 21     msgrcv(msgid,&dt,128,1,0);
 22     printf("read mess:%s\n",dt.buff);
 23 
 24     exit(0);
 25 }

演示发送消息,接收消息;
结论:

1).没有0号消息;0表示顺位接收;不管什么类型的消息都接收,因为没有0号消息,只有>=1的消息;
2).可以使用ipcrm 删除队列,也可以在程序中删除;
方法一:
ipcs  -q /-m/-s    查看
ipcrm    -q/m/s  id 删除
方法二:

msgctl(msgid,IPC_RMID,NULL);

3).如果设置成IPC_NOWAIT,没有消息不等待

if(msgrcv(msgid,&dt,128,1,IPC_NOWAIT)==-1)//没有消息不等待,返回-1
 24    {
 25        printf("no mess\n");
 26    }  
 27    else
 28    {  
 29        printf("read:%s\n",dt.buff);
 30    }

4).消息队列在内存中创建;

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪星猫宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值