Linux 基础入门操作 第九章 进程之间通讯消息队列

embedded/2024/9/24 19:12:12/

9.5 消息队列

消息队列也可以独立于发送和接收进程而存在,从而消除了在同步命名管道的打开和关闭时可能产生的困难。2、同时通过发送消息还可以避免命名管道的同步和阻
塞问题,不需要由进程自己来提供同步方法。3、接收程序可以通过消息类型有选择地接收数据,而不是像命名管道中那样,只能默认地接收。

9.5.1 创建函数

int msgget(key_t, key, int msgflg);

其他的 IPC 机制一样,程序必须提供一个键来命名某个特定的消息队列。msgflg 是一个权限标志,表示消息队列的访问权限,它与文件的访问权限一样。msgflg 可以与 IPC_CREAT 做或操作,表示当 key 所命名的消息队列不存在时创建一个消息队列,如果 key 所命名的消息队列存在时,IPC_CREAT 标志会被忽略,而只返回一个标识符。
它返回一个以 key 命名的消息队列的标识符(非零整数),失败时返回-1。

9.5.2 发送信息

该函数用来把消息添加到消息队列中。它的原型为:

int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);

msgid 是由 msgget 函数返回的消息队列标识符。
msg_ptr 是一个指向准备发送消息的指针,但是消息的数据结构却有一定的要求,指针 msg_ptr 所指向的消息结构一定要是以一个长整型成员变量开始的结构体,接收函数将用这个成员来确定消息的类型。所以消息结构要定义成这样:

struct msgbuf{
long int message_type;
/* The data you wish to transfer*/
};

msg_sz 是 msg_ptr 指向的消息的长度,注意是消息的长度,而不是整个结构体的长度,也就是说 msg_sz是不包括长整型消息类型成员变量的长度。
msgflg 用于控制当前消息队列满或队列消息到达系统范围的限制时将要发生的事情。
如果调用成功,消息数据的一分副本将被放到消息队列中,并返回 0,失败时返回-1.

9.5.3 获取信息

int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);

msgid, msg_ptr, msg_st 的作用也函数 msgsnd 函数的一样。
msgtype 可以实现一种简单的接收优先级。如果 msgtype 为 0,就获取队列中的第一个消息。如果它的值大于零,将获取具有相同消息类型的第一个信息。如果它小于零,就获取类型等于或小于 msgtype 的绝对值的第一个消息。
msgflg 用于控制当队列中没有相应类型的消息可以接收时将发生的事情。
调用成功时,该函数返回放到接收缓存区中的字节数,消息被复制到由 msg_ptr 指向的用户分配的缓存区中,然后删除消息队列中的对应消息。失败时返回-1。

9.5.4 控制函数

int msgctl(int msgid, int command, struct msgid_ds *buf);

command 是将要采取的动作,它可以取 3 个值。
IPC_STAT:把 msgid_ds 结构中的数据设置为消息队列的当前关联值,即用消息队列的当前关联值覆盖 msgid_ds 的值。
IPC_SET:如果进程有足够的权限,就把消息列队的当前关联值设置为 msgid_ds 结构中给出的值
IPC_RMID:删除消息队列
buf 是指向 msgid_ds 结构的指针,它指向消息队列模式和访问权限的结构。msgid_ds 结构至少包括以下成员:

struct msgid_ds
{
uid_t shm_perm.uid;
uid_t shm_perm.gid;
mode_t shm_perm.mode;
};

成功时返回 0,失败时返回-1.

9.5.5 参考代码

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{key_t key;int proj_id = 1;int msgid;char message1[]={"hello mrsoft!"};char message2[]={"goodbye!"};struct msgbuf{long msgtype;char msgtext[1024];}snd,rcv;
key = ftok(".",1);
if(key == -1){
perror("create key error");
return 1;
}
if((msgid = msgget(key,IPC_CREAT|0666)) == -1){
printf("magget error\n");
exit(1);
}
snd.msgtype = 1;
sprintf(snd.msgtext,"%s",message1);
if(msgsnd(msgid,(struct msgbuf *)&snd,sizeof(message1)+1,0)==-1){
printf("error");
exit(1);
}
snd.msgtype = 2;
sprintf(snd.msgtext,"%s",message2);
if(msgsnd(msgid,(struct msgbuf *)&snd,sizeof(message2)+1,0)==-1){
printf("error");
exit(1);
}
if(msgrcv(msgid,(struct msgbuf *)&rcv,80,1,IPC_NOWAIT)==-1){
printf("msgrcv error\n");
exit(1);
}
printf("the recevied message :%s.\n",rcv.msgtext);
system("ipcs -q");
msgctl(msgid,IPC_RMID,0);
exit(0);
}

http://www.ppmy.cn/embedded/116225.html

相关文章

设计模式七大原则

设计模式的七大原则是指导软件设计和架构的基本准则&#xff0c;帮助开发者创建更灵活、可维护和可扩展的系统。以下是这七大原则的详细介绍&#xff1a; 1. 单一职责原则 (SRP: Single Responsibility Principle) 定义 一个类&#xff0c;应当只有一个引起它变化的原因&…

Trainer API训练属于自己行业的本地大语言模型 医疗本地问答大模型示例

Trainer API 是 Hugging Face transformers 库中强大而灵活的工具&#xff0c;简化了深度学习模型的训练和评估过程。通过提供高层次的接口和多种功能&#xff0c;Trainer API 使研究人员和开发者能够更快地构建和优化自然语言处理模型 文章目录 前言一、Trainer API它能做什么…

vue3中使用nexttick

1、引入 import { nextTick } from vue 2、具体使用&#xff0c;配合异步 setup() {const message ref(Hello!)const changeMessage async newMessage > {message.value newMessageawait nextTick()console.log(Now DOM is updated)}} 3、具体使用&#xff0c;普通 方…

使用四叉树碰撞的游戏 显微镜RPG

实现四叉树碰撞检测 //author bilibili 民用级脑的研发记录 // 开发环境 小熊猫c 2.25.1 raylib 版本 4.5 // 2024-7-14 // AABB 碰撞检测 在拖拽&#xff0c;绘制&#xff0c;放大缩小中 // 2024-7-20 // 直线改每帧打印一个点&#xff0c;生长的直线&#xff0c;直线炮弹 /…

docker存储

docker分层结构 如图所示&#xff0c;容器是由最上面可读可写的容器层&#xff0c;以及若干个只读镜像层组成&#xff0c;创建容器时&#xff0c;容器中的 数据都来自镜像层。这样的分层机构最大的特点是写时复制&#xff1a; 1、容器中新生成的数据会直接存放在容器层&#xf…

sklearn特征选取之SelectFromModel

sklearn.feature_selection.SelectFromModel 是一种基于模型的重要性权重进行特征选择的工具&#xff0c;允许我们根据学习器的权重或特征重要性自动选择特征。它通过从模型中提取特征的重要性来选择特征&#xff0c;常用于与那些具有 coef_ 或 feature_importances_ 属性的模型…

计算机毕业设计 美发管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

Docker网络原理

Docker 网络是 Docker 容器之间以及容器与外部世界之间通信的机制。Docker 提供了多种网络驱动&#xff0c;允许容器以不同的方式进行通信&#xff1a; Docker 网络工作原理&#xff1a; 网络命名空间&#xff1a;Docker 使用 Linux 的网络命名空间来隔离容器的网络堆栈。每个…