信号量理论

个人主页:Lei宝啊 

愿所有美好如期而遇


理论

信号量是对公共资源的一种预定机制,资源不一定非要持有才算自己的,预定了也算,在未来任意时刻,仍然可以使用。

像我们申请有一块共享内存,如果一个进程正在使用,那么其他进程就需要进行等待,使得资源不会被并发访问,但是这种一次申请一块共享内存却只能由一个进程访问,效率并不高,于是就有了分配资源,将这个共享内存划分成几块,不同的进程去申请这些资源,申请成功则可以使用,失败则等待,而信号量就是对这些资源进行计数的!本质上信号量也是属于进程间通信。

于是,所有的进程在访问临界资源时,都需要去申请信号量,这也是被共同遵守的。

下面,回答几个问题,介绍几个概念:

临界资源是什么?临界资源就是被保护起来的,任何时刻只允许一个执行流访问的公共资源。访问临界资源的代码,我们叫做临界区,保护临界资源,实质上就是保护临界区。

而我们的信号量是用来保护临界资源的,访问临界资源前,需要向他申请,但是我们的信号量也是临界资源,谁来保护他呢?我们有没有一个问题,在申请和释放信号量的过程中,如果突然被打断,会发生什么?

第一个问题,信号量的申请和释放(PV操作)是原子的,由操作系统去保护,什么叫原子?原子就是一个操作不可以再被分割,是就是是,不是就是否,要么做完,要么不做。

第二个问题,他不会被打断,要么申请成功,要么就失败。

第三个问题,既然你信号量是个计数器,我直接搞一个count不就行了吗,使用他来计数不可以吗?在多进程中,我们希望每个进程都能够一直看见count的值,并且要求count++和--的操作是原子的,但是count变量++和--的操作不是原子的,在汇编层面,他会将count先写进CPU,然后CPU对他做++,然后写回变量,这个过程是可以被打断的,同时,我们无法让一个普通变量一直被多进程看到,所以我们有了信号量。

我们还可以通过他的接口可以看到他和共享内存,消息队列之间的一些共性,比如说              struct ipc_perm,三者的结构体变量中都有这样一个结构体变量,而且都放在结构体的头部,我们看图:

在操作系统内核中,是这样一个结构,看图:

而我们知道,一个结构体的地址在值上和他的第一个成员变量的值是相等的。于是我们对共享内存等的管理,就变成了对柔性数组的增删查改。(通过找到ipc_perm中的_key)

那么我们只通过ipc_perm*怎么知道哪个是共享内存,哪个是信号量?在ipc_perm中,有一个mode变量,存放着我们创建时的类型,使用宏的方式,同时我们定义了这样的宏,所以,确定类型,就变成了ipc_perm* ->mode & 宏,我们写三个接口,就可以判断类型,返回类型后对ipc_perm*类型强制类型转换,就可以进行访问了。

而我们的shmid,msgid,semid,都是柔性数组中的下标。

其实这里不好的点在于,他们的结构没有向文件靠拢,如果将他们的结构体再做一层封装,封进strcut file中,将struct file*填入数组中返回下标,这样就契合了Linux下一切皆文件,在使用时我们也能够统一看待,也就能使用统一的接口,而不是像现在这样。

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lei宝啊

觉得博主写的有用就鼓励一下吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值