【Linux】进程通信(消息队列Message Queue)

(一)消息队列

  • 消息队列与有名管道相似
  • 消息队列不需要管道的打开和关闭管道的操作
  • 消息队列并未解决管道满时的阻塞问题
(1)消息队列原理
  • 一个进程向另一个进程发送一个数据块(含有类型)
  • 接收进程可以独立地接收不同类型的数据块
  • 可以避免有名管道的同步和阻塞问题(未满状态)
  • 可以查看紧急消息
  • 每个数据块都有一个最大的长度限制(超出限制,消息队列函数失败的原因)
  • 所有队列的所有数据块的总长度也有上限
(2)Linux系统下的两个宏定义:(其它系统未知)
  • 一条消息的最大长度:MSGMAX
  • 一个队列的最大长度:MSGMNB

(二)消息队列函数

(1)创建,访问一个消息队列

int msgget(key_t key, int msgflg);

  • key : 键值,通过同一个键值来访问同一个消息队列(特殊键值IPC_PRIVATE,当前进程可用,私有队列没啥用)
  • msgflg : 必须使用IPC_CREAT 和 | 按位或才能创建新的消息队列(没有则创建,已存在则忽略)
  • 返回值 :成功返回队列标识符(正整数),失败-1
(2)添加消息到队列中

int msgsnd(int msqid, const void* msg_ptr, size_t msg_sz, int msgflg);

  • msqid : msgget的返回的消息队列标识符
  • msg_ptr : 是指向准备发送消息(数据块struct my_message{};)的指针
    约束条件:
  • 消息队列的长度小于系统规定的上限
  • 必须以一个长整形long int 变量开始(作为接收函数区分类型的标准)
    建议创建一个结构体类型:
    struct my_message
    {
    long int message_type; //消息类型 > 0
    ... /*你希望传输的数据*/
    }
  • msg_sz : msg_ptr指向消息的长度(不包含类型的字节大小)
  • msgflg : 控制此消息队列达到系统限制(队满),要发生的事。

(IPC_NOWAIT|函数不发送消息并立即返回-1)

队满情况下:如果没有请求类型的消息可用,且未指定IPC_NOWAIT,在MSGFLG中,调用过程被阻塞(等待系统的消息队列中腾出空间),直到下列条件之一:

  • 所需类型的消息放置再队列中
  • 消息队列被系统删除,系统调用失败,错误号设置为EIDRM
  • 调用进程捕获一个信号。在这种情况下,系统调用失败将errno设置为EINTR。
  • 返回值:成功返回0,失败-1
(3)从消息队列中获取消息

int msgrcv(int msaid, void* msg_ptr, size_t msg_sz, long int mstype, int msgflg);

  • msqid : 是msgget返回的消息队列的标识符
  • msg_ptr : 是一个指向准备接收消息的指针(struct my_message{long int , …};)
  • msg_sz : 是接收消息的长度(不包括消息类型字节大小
  • msgtype : 是一个长整数,可以实现简单形式的优先级(优先级消息队列)

注意:

  • msgtype为0,获取队列中第一个可用消息
  • 大于0,获取同种类型的第一条消息
  • 小于0,获取 小于或等于msgtype的绝对值的类型的第一条消息

接受类型使用场景:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值