Linux消息队列信号量(了解)

消息队列

要实现进程间通信我们必须得让不同的进程看到同一份资源, 根据这个资源的不同(文件缓冲区, 内存块, 队列) 我们将通信方式分为管道,共享内存,以及我们接下来要讲的消息队列。

消息队列的原理就是让不同的进程能看到同一个队列, 每当想发送数据就将带类型的数据块(这是为了区分消息发送给谁)链入队列中, 这样每个进程都能从队列中拿到发送给自己的数据。
在这里插入图片描述
这种通信方式和之前将的共享内存一样是system V标准

消息队列相关的接口

创建消息队列
在这里插入图片描述
控制消息队列
在这里插入图片描述
在这里插入图片描述
发送消息到消息队列, 注意我们需要发送的是类似下面那张图的结构体

从消息队列中接收消息

在这里插入图片描述

IPC在内核中的数据结构设计

在操作系统中, 所有的IPC资源, 都是在整合进程操作系统的IPC模块中

我们要管理消息队列, 共享内存, 信号量, 其实就是管理对应的数据结构
在这里插入图片描述

所以现在的问题就是我们该如何把这些数据结构管理起来呢?

在操作系统当中使用数组管理起来的。
在这里插入图片描述
我们在创建共享内存的时候, 操作系统就会为我们创建出他的_ds结构体在这里插入图片描述
我们就让数组的某个地方, 指向这个结构体的起始位置
在这里插入图片描述
后来, 如果我们要创建消息队列, 虽然他们的_ds有所不同, 但是他们的第一个数据类型是一样的, 所以同样可以将他的起始地址填入数组中
在这里插入图片描述
对于信号量也同理。

从此往后, 我要管理操作系统中的IPC资源就转化成了对该数组进行增删查改。

而我们要查找某个资源的时候只需要根据提供的key, 然后遍历数组,在指向的第一个结构体中去找到这个key

在这里插入图片描述
而这个XXXid(例如 shmid) 就是这个玩意的数组下标

我们可以发现, 其实这里也是用c语言实现的多态。

信号量

在这里插入图片描述
当我们的A正在写入, 写入了一部分还没写完就被b拿走了,导致发送和接受的信息都不完整 — 数据不一致问题

管道不会有这种问题, 因为管道有同步与互斥机制, 而共享内存是没有保护机制的。

  1. A B 看到的是同一份资源(共享资源), 如果不加以保护就会导致数据不一致问题。
  2. 加锁 – 互斥访问 – 当我读写的时候不允许别人打扰 也就是 任何时刻都只允许一个执行流访问共享资源 – 互斥
  3. 共享的, 任何时刻只允许一个执行流访问(执行访问代码)的资源他就是一个 – 临界资源 例如(管道) – 一般是内存空间。
  4. 并不是所有的代码都会访问临界资源, 例如100行代码可能只有几行在进行拷贝等操作需要访问临界资源, 我们把访问临界资源的代码称为临界区

解释一个现象: 多进程,多线程, 并发打印的时候 例如打印"hello 1234"
但是显示器上的消息:
1 错乱的
2 混乱的 (可能有的消息没有被完全打印出来)
3 和命令行混在一起
我们想显示器打印数据本质上是往显示器文件里写入数据, 所以我们会先写入显示器文佳的缓冲区内,然后操作系统再把内容刷新到显示器上我们才看到对应的内容,进程要往同一个显示器打印内容, 需要看到同一个显示器文件, 所以显示器文件在这里其实是一个共享资源, 由于没有对他进行保护, 所以导致了数据不一致问题

理解信号量

信号量的本质就是一把计数器, 类似(不是等于)int cnt = n
他是用于描述临界资源中资源数量的多少!
在这里插入图片描述

在这里插入图片描述
为了防止n + 1 个执行流去访问 n 个资源 而导致多个执行流访问同一个资源 我们就有了一个计数器 。

1 申请成功(计数器不为0) 就代表我具有访问资源的权限了。
2 申请了计数器资源, 我当前访问我要的资源了吗? 没有。 申请了计数器资源的本质是对资源的预定机制
3 计数器可以有效保证进入共享资源的执行流的数量。
4 所以每一个执行流想访问共享资源的时候, 不是直接去访问, 而是先申请计数器资源。就比如看电影要先买票。

这个计数器我们就称为信号量

而如果信号量为1, 也就代表只有一个执行流能访问这个临界资源
我们把值只能为1/0两态的计数器叫做二元信号量 – 他的本质就是一个锁。
计数器为1 本质就是不要把临界资源当做很多块了, 而是当做一个整体来使用。
在这里插入图片描述
那么对一个整数做--操作是安全的嘛?
不是
在这里插入图片描述
所以在信号量这里,对于他的操作是进行保护了的。
在这里插入图片描述

结论:
在这里插入图片描述

信号量对应的接口

申请信号量
在这里插入图片描述
第二个参数表示要申请几个信号量, 注意多个信号量和信号量是几不是一个概念

控制信号量、
根据cmd的不同对信号量进行不同的操作 比如 设置, 删除, 获取属性
在这里插入图片描述

设置信号量
在这里插入图片描述

其中sembuf是需要我们自己定义的结构体, 他的结构是这样的
在这里插入图片描述
如果我们只需要一个信号量第一个参数就传0 就相当于这个信号量在数组里的下标
sem_op 我们一般设置为1/-1 1表示对信号量实行++,也就是p操作-1表示对信号量进行-- ,也就是v操作

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值