并发 -------- 2.3 进程间的通信 - 消息队列

前言:进程间的通信方式包括


        IPC: 
            1、管道
                pipe 无名管道
                fifo 有名管道 
            2、信号 signal        
            3、消息队列 System V消息队列 / POSIX消息队列      <-----------
            4、共享内存 System V共享内存 / POSIX共享内存 
            5、信号量   System V信号量 / POSIX信号量 
            6、socket套接字


0、System V IPC的一些相关的命令 

    查看: 
        ipcs -q     查看消息队列 
        ipcs -m     查看共享内存 
        ipcs -s     查看信号量 
        ipcs -a     查看所有的IPC 

    删除: 
        ipcrm -q 消息队列id     /   ipcrm -Q 键值     删除消息队列 
        ipcrm -m 共享内存id     /   ipcrm -Q 键值     删除共享内存 
        ipcrm -s 信号量id       /   ipcrm -Q 键值     删除信号量


1、什么是消息队列 

    System V 消息队列 : 实现为一个带头结点的链表 对于系统中的每一个消息队列,内核维护在一个消息结构体中 struct msqid_ds {} (man msgctl )

               

 struct msqid_ds {struct ipc_perm msg_perm;     /* 该结构体的读写权限 Ownership and permissions */time_t          msg_stime;    /* 最后发送消息的时间 Time of last msgsnd(2) */time_t          msg_rtime;    /* 最后接收消息的时间 Time of last msgrcv(2) */time_t          msg_ctime;    /* 最后修改消息结构体的时间 Time of last change */unsigned long   __msg_cbytes; /* 当前消息队列中消息的总字节数 Current number of bytes in queue (nonstandard) */msgqnum_t       msg_qnum;     /* 当前消息队列中 消息的数量 Current number of messages in queue */msglen_t        msg_qbytes;   /* 消息队列中 允许的最大字的节数 Maximum number of bytes allowed in queue */pid_t           msg_lspid;    /* 最后发送消息的进程id   PID of last msgsnd(2) */pid_t           msg_lrpid;    /* 最后接收消息的进程id   PID of last msgrcv(2) */};

    
2、 System V 消息队列 相关的接口函数 

    1)申请 System V IPC 的键值 key 

        键值的作用 就是用来唯一标识一个 System V IPC 的对象 ,用类型 key_t 来表示  。

        ftok()  

            NAME
                ftok - convert a pathname and a project identifier to a System V IPC key
            SYNOPSIS
                #include <sys/types.h>
                #include <sys/ipc.h>

                key_t ftok(const char *pathname, int proj_id); 
                    功能:用一个路径名 和 一个整数 生成一个键值key 
                    参数: 
                        pathname: 指定一个已经存在的路径名  (例如: /home/china/ )
                        proj_id: 一个整数 
                    返回值: 
                        成功,返回一个IPC 键值key 
                        失败,返回-1,同时errno被设置

                注意:
                    调用ftok()函数多次,如果两个参数与之前一致,那么生成的键值key也相同 

    
    2)创建 或者 打开 消息队列 msgget 

            NAME
                msgget - get a System V message queue identifier
            SYNOPSIS
                #include <sys/types.h>
                #include <sys/ipc.h>
                #include <sys/msg.h>

                int msgget(key_t key, int msgflg);
                    功能:用来创建或者打开一个消息队列 
                    参数: 
                        key: 一个IPC 键值key 
                        msgflg: 标志位 
                                (1)创建标志 
                                    IPC_CREAT | 权限 
                                    例子: 
                                        IPC_CREAT | 0666 
                                    注意: 
                                        如果创建失败的原因 是因为已经存在了 
                                        且 创建的标志为 IPC_CREAT | IPC_EXCL 一起使用 
                                        此时 errno == EEXIST 
                                (2)打开标志 
                                     0  
                    返回值: 
                        成功,返回一个已经打开的消息队列id 
                        失败,返回-1,同时errno被设置 
           

                创建一个 System V 消息队列, 打印其 键值 和 id 然后 ipcs -q 查看消息队列 #define PATHNAME "/home/china/"int main() {//1.获取键值 key_t key = ftok( PATHNAME, 2 );if( key == -1 ){perror("ftok error ");return -1;}printf("key = %d\n", key );//2.创建消息队列 int msg_id = msgget( key, IPC_CREAT | IPC_EXCL | 0666 );  //不存在,则创建打开if( msg_id == -1 ){if( errno == EEXIST )  //如果存在,就直接打开{msg_id = msgget( key, 0 );}else {perror("msgget error ");return -1;}}printf("msg_id = %d\n", msg_id );}


    3)发送/接收消息 

        NAME
            msgrcv, msgsnd - System V message queue operations

        SYNOPSIS
            #include <sys/types.h>
            #include <sys/ipc.h>
            #include <sys/msg.h>

            int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
                功能:用来发送一个消息到指定的消息队列上 
                参数: 
                    msqid: 一个已经打开的消息队列id 
                    msgp: 指向要发送的消息结构体的指针 
                            struct msgbuf       //在自己代码中 根据实际情况重新定义
                            {
                                long mtype;       /* 消息类型(可以看做成编号) message type, must be > 0 */
                                char mtext[1];    /* 消息的内容,可长可短  message data */
                            };
                    msgsz:消息内容的实际的长度 (上述结构体中 metxt数据的实际的大小)
                    msgflg:发送标志 
                                0          阻塞模式(默认)
                                IPC_NOWAIT 非阻塞模式 立即返回,且 errno == EAGAIN 
                返回值: 
                    成功,返回0 
                    失败,返回-1,同时errno被设置 
         

                 发送一个消息到指定的消息队列上  struct msgbuf {long mtype;         //消息类型(可以看做成编号)  char mtext[64];     //消息内容 };int main(){//1.获取键值 //2.创建消息队列 //3.发送消息 struct msgbuf  buf;buf.mtype = 1001;fgets( buf.mtext, 64, stdin ); int re = msgsnd( msg_id, &buf, sizeof(buf.mtext), 0 );if( re == -1 ){perror("msgsnd error ");return -1;}}

            ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
                功能:用来从一个消息队列上去接收一个消息 
                参数: 
                    msqid: 一个已经打开的消息队列id 
                    msgp: 指针,指向的空间用来保存接收到的消息 
                    msgsz: msgp指针 指向的空间的大小,最多能够存放多少字节的消息 
                    msgtyp: 接收消息的类型
                                如果为0,表示接收任意类型消息 
                    msgflg:接收标志 
                                0          阻塞模式(默认)
                                IPC_NOWAIT 非阻塞模式 立即返回,且 errno == EAGAIN 
                返回值: 
                    成功,返回实际接收到的字节数 
                    失败,返回-1,同时errno被设置 

       

              利用消息队列,实现进程间通信 msgsnd.c    发送消息 msgrcv.c    接收消息 #define PATHNAME "/home/china/"struct msgbuf {long mtype;         //消息类型(可以看做成编号)  char mtext[64];     //消息内容 };int main(){//1.获取键值 key_t key = ftok( PATHNAME, 2 );if( key == -1 ){perror("ftok error ");return -1;}printf("key = 0x%x\n", key );//2.创建或打开一个消息队列 int msg_id = msgget( key, IPC_CREAT | IPC_EXCL | 0666 );  //不存在,则创建打开if( msg_id == -1 ){if( errno == EEXIST )  //如果存在,就直接打开{msg_id = msgget( key, 0 );}else {perror("msgget error ");return -1;}}printf("msg_id = %d\n", msg_id );//3.发送消息 / 接收消息 struct msgbuf  buf;buf.mtype = 1002;fgets( buf.mtext, 64, stdin ); int re = msgsnd( msg_id, &buf, sizeof(buf.mtext), 0 );if( re == -1 ){perror("msgsnd error ");return -1;}}


    4)消息队列的控制操作 msgctl 

            NAME
                msgctl - System V message control operations

            SYNOPSIS
                #include <sys/types.h>
                #include <sys/ipc.h>
                #include <sys/msg.h>

                int msgctl(int msqid, int cmd, struct msqid_ds *buf);
                    功能:用来对消息队列进行控制操作 
                    参数: 
                        msqid: 一个已经打开的消息队列id 
                        cmd: 控制命令 
                                IPC_RMID    删除消息队列  
                                IPC_STAT    获取消息队列的属性
                                IPC_SET     设置消息队列的属性 
                                ...
                        buf: 指向一个msqid_ds结构体的指针,用来保存或修改消息队列的属性  
                                根据cmd命令的不同,第三个参数有不同的情况 
                                    如果 cmd == IPC_RMID , 那么就填 NULL 
                返回值: 
                    成功,返回0 
                    失败,返回-1,同时errno被设置  
       

           获取消息队列的属性,打印 该消息队列中的消息的总字节数 和 消息的数量 #define PATHNAME "/home/china/"int main(){//1.获取键值 key_t key = ftok( PATHNAME, 2 );if( key == -1 ){perror("ftok error ");return -1;}printf("key = 0x%x\n", key );//2.创建 或 打开一个消息队列 int msg_id = msgget( key, IPC_CREAT | IPC_EXCL | 0666 );  //不存在,则创建打开if( msg_id == -1 ){if( errno == EEXIST )  //如果存在,就直接打开{msg_id = msgget( key, 0 );}else {perror("msgget error ");return -1;}}printf("msg_id = %d\n", msg_id );//3.获取消息队列的属性 struct msqid_ds  stat;int re = msgctl( msg_id, IPC_STAT, &stat );if( re == -1 ){perror("msgctl error ");return -1;}//打印 该消息队列中的消息的总字节数 和 消息的数量 printf("msg_cbytes = %ld\n", stat.__msg_cbytes );printf("msg_qnum = %ld\n", stat.msg_qnum );}


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/51859.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++/STL】:哈希 -- 线性探测哈希桶

目录 &#x1f4a1;前言一&#xff0c;unordered系列容器二&#xff0c;哈希2.1 哈希的概念2.2 哈希函数2.3 哈希冲突 三&#xff0c;哈希冲突解决(重点)3.1 开放定址法3.2 哈希桶(重点) 四&#xff0c;线性探测的实现4.1 线性探测的基本框架4.2 插入操作4.3 查找操作4.4 删除操…

Let‘s Encrypt

启动Https,需要从证书授权机构(简称CA)处获取一个证书,Lets Encrypt就是一个CA Lets Encrypt上可以获得免费的ssl证书,时间是3个越 下面通过Nginx和Lets Encrypt让网站升级到HTTPS Certbot简介 Certbot是Lets Encrypt官方推荐的获取证书的客户端 Centos 7.9操作 yum install …

openai版本不适配问题(在windows系统下openai migrate)

问题如下&#xff1a; 方法&#xff1a; 参考官网v1.0.0 Migration Guide openai/openai-python Discussion #742 GitHub 具体步骤&#xff1a; 1、curl -fsSL https://docs.grit.io/install | bash -x 但该命令可能不好用————将‘curl -fsSL https://docs.grit.io/i…

谷歌AI拿下IMO奥数银牌,数学推理模型AlphaProof面世,强化学习 is so back

用上了 Gemini 大模型与 AlphaZero 强化学习算法,几何、代数、数论全都会。 对于 AI 来说,奥数不再是问题了。 本周四,谷歌 DeepMind 的人工智能完成了一项壮举:用 AI 做出了今年国际数学奥林匹克竞赛 IMO 的真题,并且距拿金牌仅一步之遥。 上周刚刚结束的 IMO 竞赛共有…

深入分析 Android ContentProvider (九)

文章目录 深入分析 Android ContentProvider (九)ContentProvider 的高级使用及最佳实践&#xff08;续&#xff09;1. 复杂查询与联合查询复杂查询示例 2. 数据同步与一致性示例&#xff1a;使用事务确保数据一致性 3. 数据分页加载示例&#xff1a;分页加载数据 4. 内容提供者…

【CN】Argo 持续集成和交付(二)

7.25.通知 概述 Argo CD 通知持续监控 Argo CD 应用程序&#xff0c;并提供一种灵活的方式来通知用户应用程序状态的重要变化。使用灵活的触发器和模板机制&#xff0c;可以配置何时发送通知以及通知内容。Argo CD 通知包含有用的触发器和模板目录。因此&#xff0c;可以直接…

【Pycharm中anaconda使用介绍】

在安装好anaconda之后&#xff0c;首先打开anaconda界面&#xff0c;执行以下操作 1.查看Anaconda中当前存在的环境 conda info -e 或者 conda-env list 查看–安装–更新–删除包 conda list&#xff1a; conda search package_name 查询包 conda install package_name conda …

pycharm连接mysql

1、按照下图在pycharm找到数据库设置 在PyCharm右侧工具栏有Database&#xff0c;点击打开如果没有&#xff0c;则在view | Tool Windows | Database 选择显示 2、按照下图所示位置找到mysql&#xff08;本机由于配置过&#xff0c;所以由recent&#xff0c;第一次配置在列表中…

Cybersecurity ASPICE实施策略-基于ISO/SAE 21434-亚远景科技

近几年&#xff0c;随着软件定义汽车和汽车的智能化和网联化&#xff0c;使得汽车融合了现代通信与网络通信技术&#xff0c;实现了车与人、车与车、车与道路、车与云端等智能信息交互和共享&#xff0c;也让车具备了环境感知、协同控制、智能决策等功能&#xff1b;与此同时&a…

vue3子组件调用父组件方法 使用prop

父组件Father.vue <template><Child :parentMethod"parentMethod" /> </template><script setup> import { defineComponent } from vue; import Child from ./Child.vue;const parentMethod () > {console.log(这是父页面的一个方法);…

苹果推送iOS 18.1带来Apple Intelligence预览

&#x1f989; AI新闻 &#x1f680; 苹果推送iOS 18.1带来Apple Intelligence预览 摘要&#xff1a;苹果向iPhone和iPad用户推送iOS 18.1和iPadOS 18.1开发者预览版Beta更新&#xff0c;带来“Apple Intelligence”预览。目前仅支持M1芯片或更高版本的设备。Apple Intellige…

使用 Elasticsearch 和 LlamaIndex 保护 RAG 中的敏感信息和 PII 信息

作者&#xff1a;来自 Elastic Srikanth Manvi 在这篇文章中&#xff0c;我们将研究在 RAG&#xff08;检索增强生成&#xff09;流程中使用公共 LLMs 时保护个人身份信息 (personal identifiable information - PII) 和敏感数据的方法。我们将探索使用开源库和正则表达式屏蔽 …

正余弦算法作者又提出新算法!徒步优化算法(HOA)-2024年一区顶刊新算法-公式原理详解与性能测评 Matlab代码免费获取

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 原理简介 算法伪代码 性能测评 参考文献 …

基于vue-onlyoffice实现企业office web在线应用

目录 1.背景... 1 2.Onlyoffice介绍... 2 3.Onlyoffice核心api介绍... 2 3.1 ApiDocument 2 3.2 ApiParagraph. 2 3.3 ApiTable. 2 3.4. ApiRange. 3 4.Onlyoffice插件介绍... 3 4.1 插件定义... 3 4.2 插件对象... 3 4.3 插件结构... 4 4.4 插件内嵌使用方式... 4…

搜索引擎项目(四)

SearchEngine 王宇璇/submit - 码云 - 开源中国 (gitee.com) 基于Servlet完成前后端交互 WebServlet("/searcher") public class DocSearcherServlet extends HttpServlet {private static DocSearcher docSearcher new DocSearcher();private ObjectMapper obje…

Luma AI发布文生视频大模型Dream Machine——可免费在线试玩

Sora模型的文生视频能力&#xff0c;想必一定惊艳过你。虽然Sora模型很惊艳&#xff0c;但是并没有开放给普通大众。Luma AI发布文生视频大模型Dream Machine模型&#xff0c;可以免费供大家使用&#xff0c;任何人只要到Luma AI的官方网站&#xff0c;就可体验Luma AI的文生视…

java使用JNA调用C/C++动态库,char*无法转换问题

java使用JNA调用C/C动态库&#xff0c;char*无法转换问题 例如&#xff1a; C如下写法 char* test01(const char* &name, const int &age);对应&#xff1a; java中序如下写法 //导入的包 import com.sun.jna.Pointer;//java中需要对应的写法 Pointer test01(String…

六个开源的PDF转Markdown项目

✨ 1: gptpdf gptpdf 是一个利用VLLM解析PDF为Markdown的工具&#xff0c;几乎完美支持数学公式、表格等。 GPTPDF 是一个使用视觉大模型&#xff08;如 GPT-4o&#xff09;将 PDF 文件解析成 Markdown 文件的工具。它主要用于高效地解析 PDF 文档中的排版、数学公式、表格、…

React Native新架构系列-新架构介绍

从今天起&#xff0c;会陆续更新React Native新架构相关的系列内容&#xff0c;本系列基于React Native 0.73.4版本&#xff0c;从一名Android开发者的视角进行介绍。本系列介绍的内容默认读者对React Native有一定的了解&#xff0c;对基础的开发内容不再赘述。 前言 首先介绍…

【优选算法】——leetcode——438.找到字符串中所有字母异位词

目录 1.题目 2.题目理解 3.算法原理 1.如何快速判断两个字符串是否是异位词 2.解决问题 暴力求解——>滑动窗口哈希表 滑动窗口 利用滑动窗口哈希表解决问题 优化&#xff1a;更新结果的判断条件 4.编程代码 C代码 1.频率统计 2. 双指针 C语言代码 1.字符频率…