【Linux:文件 + 进程】进程间通信进阶(2)

【Linux:文件 + 进程】进程间通信进阶(2) 个人主页艾莉丝努力练剑❄专栏传送门《C语言》《数据结构与算法》《C/C干货分享学习过程记录》《Linux操作系统编程详解》《笔试/面试常见算法从基础到进阶》《Python干货分享》⭐️为天地立心为生民立命为往圣继绝学为万世开太平 艾莉丝的简介文章目录7 ~ 消息队列7.1 消息队列的概念7.2 消息队列的原理7.3 消息队列的接口7.4 消息队列的一些命令8 ~ 信号量8.1 概念补充8.1.1 共享资源和临界资源8.1.2 互斥和同步8.1.3 和程序员有什么关系8.1.4 临界区和8.1.5 保护访问公共资源的代码8.1.6 补充概念思维导图8.2 信号量的三个问题8.2.1 概念信号量是什么8.2.2 信号量的本质8.2.3 理解8.2.4 补充故事如果今天电影院的放映厅里面只有一个座位呢8.2.5 信号是什么的思维导图8.2.6 为什么要有信号量8.2.7 怎么办6.2.8 信号量怎么办的思维导图结尾7 ~ 消息队列7.1 消息队列的概念这个消息队列是系统层面的概念不是组件级别的和未来组件里的消息队列不是一个东西。所谓的消息队列就是在操作系统里面维护一个队列结构。7.2 消息队列的原理消息队列——操作系统提供的IPC结构。也会存在一个由用户设置的key值A、B进程都能够看到约定好的。双方通过往消息队列里面插入节点来进行通信。消息队列在内核中也要存在一个描述结构体。消息队列也有自己的结构体看到自己的键值。消息队列和共享内存都是系统级的IPC。如果这个数据节点只有数据操作系统怎么区分这是A的还是B的必须保证这种数据块是有类型的数据块消息队列是一种一个进程给另一个进程发送有类型数据块的方式我们需要的系统调用7.3 消息队列的接口7.4 消息队列的一些命令查看消息队列删除消息队列8 ~ 信号量在共享内存那里我们知道使用共享内存的时候共享内存没有保护机制信号量可以保护共享内存。在共享内存这里先谈理论部分在线程那里再谈别的。这里我们重点理解信号量是什么的问题8.1 概念补充当你学了管道可能对“看到同一份资源”没有强烈的感觉但是学了信号量就可以了——多进程通信最重要的是让不同的进程看到同一份资源解决方案不同的进程看到同一份资源 - 新的问题也就从这里展开了新的解决方案引入新的问题硬币也有正反、有钱了解决了现在的问题但是又有一大批人来借钱了、……。问题对同一个进程进行访问的时候会出现并发访问出现错误的问题比如刚才的两个写端的互相清空覆盖的现象同时打开两个写端——互相干扰。8.1.1 共享资源和临界资源我们现阶段是处在“并发访问出现错误”的阶段。我们把多个执行流进程能够看到的公共资源叫做共享资源把被保护起来的资源叫做临界资源。8.1.2 互斥和同步任何时刻只允许一个执行流访问资源就叫做互斥只允许我一个人访问比如ATM机器取钱、上厕所关门等等——不想被别人打扰就是互斥访问——ATM机就是这个临界资源有了顺序性就是同步。让多个进程执行的时候一定要有顺序按顺序执行——同步。一个进程在等另一个进程。互斥与同步 共享资源 临界资源被保护的共享资源8.1.3 和程序员有什么关系不管是同步、互斥共享资源、临界资源上面这些工作具体和程序员有什么关系我程序员就是个写代码的啊为了更好地理解再举一个例子父子进程打印内容错乱、没有规律一会儿打父进程的、一会儿打子进程的。大家有没有遇到过父子进程都往同一个显示器上面打印消息的时候发生错乱的这种情况这是因为Linux下一切皆文件stdout其实是一个共享资源我们父子进程向它打印的时候这个共享资源是没有被保护起来所以会出现这种现象我们要保护的话需要同步与互斥这种机制。所以并发错乱的问题我们早就遇到过了。Linux下一切皆文件显示器也是文件设备文件在这里属于共享资源这里的显示器是没有被保护的数据不一致这里先不说为了防止【错乱】要通过同步和互斥来保护显示器这个共享资源。为什么突然说这个8.1.4 临界区和一定要记住所谓的共享资源站在程序员的视角将来程序员也是通过代码访问共享资源的未来程序员所写的代码有的代码是会访问共享资源同样的有的代码不会访问共享资源。把访问公共资源的代码叫做【临界区】把不访问公共资源的代码叫做【非临界区】。在进入临界区之前进行加锁离开时解锁。通过加锁、解锁——写代码的方式要改把临界资源保护起来8.1.5 保护访问公共资源的代码保护访问公共资源的代码8.1.6 补充概念思维导图8.2 信号量的三个问题一看到问题我们就会想到高中语文学习时候的三个问题是什么为什么怎么办我们学习信号量的时候也可以迁移这种发问的思想。8.2.1 概念信号量是什么很多教材里面喜欢管信号量叫做“信号灯”——被翻译过来的。信号量用来实现同步和互斥的一种技术。场景公共资源 - 把公共资源当做整体访问ATM机器也有局部使用电影院看电影一个座位。8.2.2 信号量的本质信号量本质是一个计数器用来衡量临界资源中资源数量的计数器可以想象成一个int count——计数器就是信号量的本质。8.2.3 理解我们基本上没见过电影院放印厅因为座位发生争执的因为电影院就那么多座位也只会放最多这么多人进来。座位真正属于你的时候是什么时候——买票的时候只要买到了票必然有座位。票卖完了也很正常说明总票数是一个计数器本身是有上限的我们可以通过买票的操作对这个计数器进行减减--。1、买票2、坐在你的座位上-本质上就是你已经开始访问这个资源了我只要把票买了这个座位就是属于我了。相当于我提前预定了其他人不能占我的位置。换言之我只要买了票就一定会有一个资源属于我。所以买票的本质对共享资源的一种预定机制在我们今天来看我们可以把这个放映厅想成内存块。一个个人就是一个个进程。就像我人要买票每一个进程也需要对应的操作才能访问也就是先申请信号量所以我们进入临界区对这个计数器------P()走了V()。申请信号量这个操作的本质就是对临界区资源进行预定。我们来写一个不太严谨的伪代码来帮助理解一下8.2.4 补充故事如果今天电影院的放映厅里面只有一个座位呢8.2.5 信号是什么的思维导图8.2.6 为什么要有信号量因为有问题并发访问 ~ 信号量 ~ 为了解决多进程访问共享资源产生的并发读写问题。8.2.7 怎么办怎么办我们就来了解一下信号量的一些接口怎么设计信号量怎么创建信号量我们先来看一下信号量的一些接口——创建信号量semget操作系统允许创建信号集信号量集删除信号量的系统调用共享内存信号量在操作系统角度是怎么被“先描述再组织”的我们先来看看信号量集——这个5指的是信号量集里面有五个。信号量本质是个计数器对信号量进行操作的时候用semctl不光是删除操作包括获取、删除、……系统提供的枚举类型的结构体传进去就可以处理初始值获取信号量集的信息信号量集的创建时间什么的——这个结构体 struct semid_ds 用于描述 System V 信号量集的关联信息。通过它你可以获得信号量集的创建时间sem_ctime同时还能获取以下信息怎么保证看到的是同一个信号量集信号量这里的op和共享内存那里一样通常是1或者-1代表要进行什么操作sembuf结构体是semop()系统调用用来描述单个信号量操作的核心数据结构。它包含的三个成员sem_num、sem_op和sem_flg分别决定了操作的对象、操作的类型以及行为标志。下面详细解释每个成员的作用。这个sem_num是什么我们来看一段作为示例的代码片段#includesys/sem.h// 假设已经通过 semget() 获得了一个信号量集的标识符 semidstructsembufsb;// 对信号量集索引为 0 的信号量执行 P 操作获取资源sb.sem_num0;// 第 1 个信号量sb.sem_op-1;// 想要减少 1sb.sem_flgSEM_UNDO;// 进程退出时自动还原if(semop(semid,sb,1)-1){perror(semop);// 错误处理}else{// 成功获取资源可以进入临界区}总结一下sem_num指定操作哪个信号量索引。sem_op定义增减值或等待条件。sem_flg控制阻塞行为与自动撤销。这三个成员共同决定了semop()如何修改或等待信号量是实现进程同步与互斥的基础。最下面这个回滚就不说啦很麻烦上面说的了解一下就行。信号量创建、开辟空间是分开的6.2.8 信号量怎么办的思维导图结尾uu们本文的内容到这里就全部结束了艾莉丝在这里再次感谢您的阅读结语希望对学习Linux相关内容的uu有所帮助不要忘记给博主“一键四连”哦往期回顾【Linux文件】进程间通信进阶1博主在这里放了一只小狗大家看完了摸摸小狗放松一下吧૮₍ ˶ ˊ ᴥ ˋ˶₎ა