三个同步问题
- 生产者-消费者问题
- 哲学家进餐问题
- 读者-写者问题
生产者-消费者问题
注:所有的都是,当缓冲池满了,生产者就不可往进存放,必须等待;当缓冲池空了,消费者就不可从中取出,必须等待
1.记录型信号量方法
定义:
semaphore: 信号量
wait:(P操作)申请资源
signal:(V操作)释放资源
S:可用资源数目;当S<0, 表示有某些进程正在等待该资源,S的绝对值表示当前等待资源的进程数
mutex:互斥信号量(互斥锁)
empty: 表示缓冲池中空缓冲区数量
full:表示缓冲池中满缓冲区数量(这两个称为资源信号量)
临界区:每个进程中访问临界资源的那段代码叫临界区
进入区:临界区前,用于检查临界资源是否正在被访问的那段代码,可进入临界区则改标志为被访问;作用:申请资源
退出区:临界区后,用于将临界区正在被访问的标志恢复为未被访问的那段代码;作用:释放资源
假定生产者与消费者中有n个缓冲区(临界资源包含缓冲区):利用mutex实现进程对缓冲区的互斥作用,利用信号量empty和full表示表示缓冲区的空的和满的数量。假定生产者消费者等效,缓冲区未满,生产者才能把消息送入缓冲池;缓冲区未空,消费者才能从缓冲区中取出一个消息。 伪代码如下:
Var mutex, empty, full: semaphore := 1, n, 0; //设置各个初始值
buffer: array[0, ..., n-1] of item; //代表缓冲区,用来存放消息
in, out: integer := 0, 0; //存入,取出地址初始值(类似指针)
begin
parbegin //生产者
proceducer: begin
repeat
...
producer an item nextp; //生产者“生产”一个消息
...
wait(empty); //生产者申请一个空缓冲区(即申请访问临界资源)
wait(mutex); //进程进入临界区,加锁,使其他进程无法访问该临界资源
buffer(in) := nextp; //把消息存入缓冲区(访问临界资源)
in := (in + 1) mod n; //存入地址指向下一个缓冲区