🌻个人主页:路飞雪吖~
🌠专栏:Linux
目录
一、了解消息队列
✨消息队列函数
🍔ftok() --- 系统调用设置key
🍔 msgget()
🍔msgctl()
🍔msgsnd()
✨消息队列的管理指令
二、了解system V信号量
✨信号量函数
🍔semget() --- 获取信号量
🍔semctl
🍔semop --- 对指定信号量进行特定操作
✨信号量的管理指令
✨并发编程
三、理解内核管理IPC资源的方式,了解C实现多态
🌟System V是如何实现IPC的?和管道为什么不同呢?
✨应用角度:看IPC属性
✨内核角度:看IPC结构
一、了解消息队列
system V消息队列是内核提供的一种进程间通信的方式。
🌟原理:
操作系统内部提供一个队列queue,操作系统里面的数据和相关的数据结构,是可以被所有进程共享的,两个进程【进程A,进程B】,操作系统给这两个将要通信的进程提供一个队列【在操作系统维护的队列】和数据块【struct data】,用户上层定义一个struct data的对象,进程A 想发给 进程B,把 struct data的对象 通过系统调用,把这个对象放入到操作系统的队列当中,这个队列进程A和进程B都能看到,进程A向这个queue里放节点,进程B就可以从queue里面拿节点 ---- 消息队列。进程B也可以向进程A发送消息【双向通信】,进程B也可以把自己对应的数据节点也链入这个公共的队列当中,进程双方就可以各自的去拿对方的队列节点了。
🪄消息队列的本质:一个进程向另一个进程发送【双向通信】有类型数据块的方法。
✨消息队列函数
🍔ftok() --- 系统调用设置key
与共享内存类似。
• IPC_CREAT:若单独使用,如果消息队列不存在,就创建;存在就获取它,并返回 --- 保证调用进程能拿到共享内存。
• IPC_EXCL:单独使用无意义;
• IPC_CREAT | IPC_EXCL :若消息队列不存在,就创建它;若存在,出错返回 --- 只要成功,一定是新的消息队列,不拿老的消息队列。
• key_t key :系统调用接口的参数;
🍔 msgget()
🍔msgctl()
🍔msgsnd()
✨消息队列的管理指令
• ipcs -q :查看消息队列的属性
• ipcrm -m msqmid :删除指定的消息队列
二、了解system V信号量
✨信号量函数
🍔semget() --- 获取信号量
🍔semctl
🍔semop --- 对指定信号量进行特定操作
✨信号量的管理指令
• ipcs -s:查看信号的属性
• ipcrm -s semid :删除指定的信号
✨并发编程
• 多个执行流(进程),能看到的同⼀份公共资源:共享资源。
• 被保护起来的资源叫做临界资源。
• 保护的方式常见:互斥与同步。
• 任何时刻,只允许⼀个执行流访问资源,叫做互斥。
• 多个执行流,访问临界资源的时候,具有⼀定的顺序性,叫做同步。
• 系统中某些资源⼀次只允许⼀个进程使⽤,称这样的资源为临界资源或互斥资源。
• 在进程中涉及到互斥资源的程序段叫临界区。你写的代码=访问临界资源的代码(临界区)+不访问 临界资源的代码(非临界区)。
• 所谓的对共享资源进行保护,本质是对访问共享资源的代码进行保护。
✨信号量
🌠
• 信号量 != 信号,这两个没有任何关系。
• 信号量特性:IPC资源必须删除,否则不会自动清除,除非重启,所以system V IPC资源的生命周期随内核。
• 理解:信号量是一个计数器;
• 作用:保护临界区;
• 本质:信号量本质是对资源的预定机制;
• 操作:
1> 申请资源,计数器--,P操作。
2> 释放资源,计数器++,V操作。
• 几十个进程把共享内存挂接到自己的地址空间,所有的进程通过某种方式,让不同的进程访问共享内存,不同的子区域,即不同的进程,访问共享资源,具有一定的并发性!
当过量进程,进入临界资源,规定定义一个计数器【int count = 16】,当有一个进程进入共享资源,【if ( count > 0) count--; else wait;】若计数器大于零,计数器--,否则进行等待。这样子就可以保证进入到公共资源的进程一定是可以是多个,但可以保证上限是16个。即在共享资源内部,只要进程进来了,就能保证内部资源划分是合理的,而且不会出现冲突。
• 资源的整体和不是整体使用是一样的,资源的整体使用,就相当于【count = 1 互斥】只允许一个进程进来。
• 申请计数器成功了,就等同于预订了共享资源的某一个资源【计数器不仅是计数,也是对资源的预订】。
• 对资源进行预订机制的计数器 --- 信号量【信号灯】。
• 只有两态的计数器【资源整体使用】--- 二元信号量【1 or 0 锁】
🍧🦋计数器【int count】,能在多进程之间被看到,被修改,被访问吗?不能!!【两个毫不相干的进程,不可能看到同一个count;父子进程能看到全局的count,但是看到的count是一个假象,当有一方发生改变的时候,就会发生写时拷贝,即父进程count--,子进程却没有--,所以父子进程用全局变量来维护全局资源是做不到的】,所以 信号量这个计数器,必须想办法解决这个问题。
🍧🦋假设:多个进程能看到同一个计数器了 && 进程访问资源都得先申请计数器,那么计数器就反而变成了公共资源了,计数器怎么保证自己得安全呢?【if(count > 0) count--; else wait;】P操作和【count++】V操作 要么不访问,要么访问没人中断 --- 原子性。
🍧🦋 信号量 必须解决 : 1. 多进程信号量是个计数器,必须得想办法让不同得进程先得看到同一个信号量。2. 信号量必须保证原子性++和-- 。
🍧🦋 信号量为什么被归类到系统的IPC?原因是让不同的进程进行通信,得先让不同得进程看到同一份资源,而信号量这个计数器要让多进程看见,所以只要把信号量归结到系统IPC里面,信号量这个计数器就可以保证不同的进程看到同一个信号量了。
是因为它本质上提供了一种 协调多个进程/线程对共享资源的访问 的方式。尽管信号量本身不直接传输数据,但它解决了进程间或线程间的 同步与互斥 问题,这是 IPC 的核心功能之一。
三、理解内核管理IPC资源的方式,了解C实现多态
🌟System V是如何实现IPC的?和管道为什么不同呢?
✨应用角度:看IPC属性
推测:在OS层面,IPC是同类资源!
🌠能直接使用的各种数据提供的类型有三方:
• 语言提供【内置类型】:int、char、double、float....
• 库提供:string、vector、size_t.....
• 系统提供:shmid_ds......
✨内核角度:看IPC结构
IPC资源一定是全局的资源!被所有进程看到!
如若对你有帮助,记得关注、收藏、点赞哦~ 您的支持是我最大的动力🌹🌹🌹🌹!!!
若有误,望各位,在评论区留言或者私信我 指点迷津!!!谢谢 ヾ(≧▽≦*)o \( •̀ ω •́ )/