1.先讲进程同步与互斥
进程互斥(mutex):进入临界区的进程只能有一个,当然前提是这些进程有共同的临界区。
进程同步:有逻辑关联的进程先后执行,比如B只有等A执行完了才能执行,A没执行完进程B只能挂起。这实际上是一种约束,更是一种通信。需要同步的进程之间不一定有共享临界区。
1)禁用硬件中断和基于硬件的原子操作(testandset以及exchange)单纯实现了进程互斥;
2)基于软件(peterson算法以及面包店算法)肯定实现了互斥,同时实现了同步;
3)信号量可以但不一定实现互斥(不是说不能,一种情况是不存在共享临界区,谈不上互斥,另一种情况是允许共同进入临界区,比如读操作),肯定实现了同步。
2.信号量
1)信号量(sem)是一个整型数字,程序开始需要给它一个初值,这里我们假设初值为org,其意义我们在后面根据信号量类型分开讨论。
sem=new Semaphore(org);
2)信号量有两个原子操作:P操作和V操作,具体意义也要分信号量类型的情况
·P() : sem减1
·V() : sem加1
3.信号量类型
1)二进制信号量
此时信号量的org初值只能是0和1。
2)一般/计数信号量
此时信号量的org初值可以是任意非负数。显然,其包含二进制信号量。
以下仅谈初值:
4.信号量意义
PV过程中信号量大于0和小于0时,其代表的意义是不同的,这正是信号量的精妙所在。
当信号量≥0时,其表示还有sem个进程被允许进入临界区(某区域中还有sem个资源可以被获得),此时在临界区中的进程数目为org-sem(被取走的资源数目)。
当信号量<0时,表示有 |信号量| 个进程之前请求进入但不被允许后挂起的进程数目(想获得资源但目前给不了的进程数目),此时临界区中的进程数目为org(被拿走的资源数目),总的已经进入和即将进入的进程数目为org+|sem|(资源的总需求数目)。
允许多个线程进入的临界区限流?和缓存区资源的获取是信号量应用的两个主要方面。
5.例子:有界缓冲区的生产者消费者问题
lock只能完成互斥要求,难以完成同步约束。消费者取不到东西会形成自旋,此时使用信号量主要使用其调度功能(何时挂起?何时唤醒?)。
V操作不会引起阻塞挂起,因此顺序可换,P操作会引起阻塞挂起,调换顺序可能引起死锁。
6.信号量实现
PV操作都是原子指令。
7.小结
信号量的双用途:互斥与同步
信号量的优点:无忙等
信号量这块本来就错综复杂,各种概念交织,总结成这样尽力了,就这样吧。。。。
参考:清华大学Chen Yu老师《操作系统原理》