什么是进程同步
控制进程执行的顺序,以使并发执行的进程之间能有效的共享资源和相互合作,使程序具有可在现性(多次执行程序的结果相同)
经典同步模型:生产者消费者模型
缓冲池大小为n,生产者进程将生产出来的产品放入缓冲区,消费者进程从缓冲区中取走产品去消费。生产者进程和消费者进程之间需保持同步,生产者进程不能向一个已经装满产品且未被消费的缓冲池投放产品,消费者也不能到一个空的缓存池中消费。
进程同步的方式
1. 临界资源
在生产者消费者模型中,我们很容易会想到使用一个count
变量维护缓冲池中产品的数量,count
的初始化值为0,当生产者进程往生产者生产一个产品,count+1
,当消费者进程往缓冲池中取走一个产品,count-1
。但不控制消费者进程和生产者进程对count
变量的访问会使程序运行结果不可控。如果将count
变量申明为临界资源,同一时刻只能有一个进程访问count
即互斥访问
2. 临界区
需要互斥访问的代码块称为临界区。每个进程进入临界区前需要检查该断代码块是否被访问,如果没有被访问,则进入并设置一个正被访问的标志,退出临界区则需要将标志设置为未被访问,每次进入临界区都需要检查这个标志。临界区同步伪代码如下:
entry section
doSomething()
exit section
entry section
:检测临界资源&更改临界区访问标志(检测到未被其他进程访问)
exit section
:更改临界区访问标志
3. 信号量
- 整型信号量
定义:一个用于表示资源数目的整型量S
。不是普通的整型变量,除了初始化以外,仅能通过两个原子操作访问wait(S)
和signal(S)
来访问。wait(S)
操作:请求资源,signal(S)
操作:归还资源
伪代码如下:
wait(S): while S <= 0 do no-op; //未获取到资源则不断检查
S:=S-1;
signal(S): S:=S+1;
- 记录型信号量
整型信号量中未获取到资源则不断检查未遵循同步机制的让权等待原则(见注释一),使进程进入忙等的状态。记录型信号量在原来整数型信号量的基础上,维护一个进程链表指针L,将所有等待的进程加入链表中 - AND型信号量
AND型信号量出现是为了解决多个资源共享的问题。即一个进程需要先获取两个或更多的资源才能执行。当进程同时要求的资源越多,出现死锁问题的几率就越大。AND型信号量:一次性将需要的共享资源分配给某个资源,又一次性的回收资源 - 信号量集
信号量集出现是为了解决1.批量分配 2.设置资源下限的问题
当一次需要N个某类临界资源时,便要进行N次wait(S)
操作,效率非常低。也有场景在分配之前需要判断资源的数量是否低于某个下限值。这时候可以使用信号量集,信号量集是在AND型信号量机制上加以扩充的
4. 管程
管程的出现:每个访问临界资源的进程都需要自备同步操作wait(S)
和signal(S)
,会使大量的同步操作分散在各个进程中不利于管理,又因为是显示的使用wait(S)
和signal(S)
,会因为使用不当导致系统死锁。
管程介绍:是一种进程同步工具。简单的说管程临界资源数据结构+一组对临界资源的操作。管程中的数据结构只能被定义于该管程中的操作所访问,管程中的操作只能访问定义于该管程中的数据结构。管程相当于围墙,所有进程访问临界资源时,都必须经过管程中的操作才能访问到,并且每次只允许一个进程进入管程,即是互斥的
注释一:
同步机制应遵循的规则
- 空闲让进
当无进程进入临界区时,相应的临界资源处于空闲状态,因而允许一个请求进入临界区的进程立即进入自己的临界区。 - 忙则等待
当已有进程进入自己的临界区时,即相应的临界资源正被访问,因而其它试图进入临界区的进程必须等待,以保证进程互斥地访问临界资源。 - 有限等待
对要求访问临界资源的进程,应保证进程能在有限时间进入临界区,以免陷入“饥饿”状态。 - 让权等待
当进程不能进入自己的临界区时,应立即释放处理机,以免进程陷入忙等
网友评论