经典进程同步问题总结

关键词:进程同步;生产者-消费者问题;读者-写者问题;哲学家进餐问题

信号量机制可以实现互斥、同步、对一类系统资源的申请和释放。
一般来说,要实现互斥,可以设置初值为1的互斥信号量,在访问临界区之前,对这个信号量执行P操作,在访问临界区之后,对这个信号量执行V操作;
实现同步,可以设置初值为0的同步信号量(实现“一前一后”),在前操作之后,对同步信号量进行V操作,在后操作之前,对同步信号量执行P操作;
对于一类系统资源的申请和释放,可以设置一个信号量,初始值即为资源的数量(本质上也属于“同步问题”,若无空闲资源,则申请资源的进程需要等待别的进程释放资源之后才能继续往下进行)。
PV操作题目分析步骤:

  1. 关系分析。找出题目中描述的各个进程,分析它们之间的同步、互斥关系;
  2. 整理思路。根据各进程的操作流程确定P、V操作的大致顺序;
  3. 设置信号量。并根据题目条件确定信号量初值。(互斥信号量初值一般为1,同步信号量的初始值要看对应资源的初始值是多少)。

一、 生产者-消费者问题

(一) 问题描述

系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品并使用。生产者、消费者共享一个初始为空、大小为n的缓冲区。

(二) 问题分析

只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待。(同步关系)
只有缓冲区不空时,消费者才能从中取出产品,否则必须等待。(同步关系)
缓冲区是临界资源,各进程必须互斥地访问。假如系统中有两个生产者进程,当这两个生产者进程检查缓冲区为空时,一个生产者进程向缓冲区充入了一个产品(数据),在并发的环境下,另一个生产者进程也向缓冲区的同一个位置充入了它的产品(数据),这就导致了前者的数据被前者的数据所覆盖。(互斥关系)
生产者每次要消耗(P)一个空闲缓冲区,并生产(V)一个产品。消费者每次要消耗(P)一个产品,并释放一个空闲缓冲区(V),往缓冲区放入/取走产品需要互斥。刚开始空闲缓冲区的数量为n,非空闲缓冲区(产品)的数量为0。

(三) 问题实现

有产品(缓冲区没空) V------- full-------->P 消费者消费
生产者生产 P<---- empty------V 缓冲区没满

semaphore mutex = 1;//互斥信号量,实现对缓冲区的互斥访问
semaphore empty = n;//同步信号量,表示空闲缓冲区的数量
semaphore full = 0; //同步信号量,表示产品的数量,也即非空缓冲区的数量

producer () {
   
while (1) {
   
生产一个产品;
P(empty);         //消耗一个空闲缓冲区②
P(mutex);         //实现互斥是在同一进程中进行一对PV操作①
把产品放入缓冲区;
V(mutex);
V(full);          //增加一个产品*
}
}
consumer () {
   
while(1){
   
P(full);          //消耗一个产品(非空闲缓冲区)*④
P(mutex);         //③
从缓冲区取出一个产品;
V(mutex);
V(empty);
使用产品;        //增加一个空闲缓冲区
}
}

*实现两进程的同步关系,是在其中一个进程中执行P,另一进程中执行V。

(四) 问题延伸

  1. 若将操作①②位置调换,即互斥的mutex 的P操作在前,同步的empty的P操作在后,会发生什么情况?
    如果此时缓冲区内已经放满产品,意味着空闲缓冲区empty=0,非空闲缓冲区(产品数量)full=n。则生产者进程执行① 使mutex变为0,再执行②,由于已没有空闲缓冲区,因此生产者被阻塞。
    由于生产者阻塞,因此切换回消费者进程。消费者进程执行③,由于mutex为0,即生产者还没释放对临界资源的“锁”,因此消费者也被阻塞。这就造成了生产者等待消费者释放空闲缓冲区,而消费者又等待生产者释放临界区的访问权限,生产者和消费者循环等待被对方唤醒,因此出现了“死锁”现象。
    同样的,若缓冲区中没有产品,即full=0,empty=n。按③④① 的顺序执行就会发生死锁。
    因此,实现互斥的P操作一定要在实现同步的P操作之后。V操作不会导致进程阻塞,因此两个V操作顺序可以交换。
  2. 能否将生产者进程的生产一个产品操作和消费者进程的使用产品操作放到PV操作之间呢?
    逻辑上来看是没有问题的,可以让消费者从缓冲区取出一个产品之后,就紧接着使用产品,但这会导致临界区的代码量变大,那么消费者进程在访问临界区就需要耗费更长的时间,如果此时有别的进程也想访问临界区的话,就会被阻塞。如果把非必要的代码也放入临界区的话,就会导致程序之间的并发度降低。

二、 读者-写者问题

(一) 问题描述

有读者和写者两组并发进程,共享一个文件,当两个或两个以上的读进程同时访问共享数据时不会产生副作用,但若某个写进程和其他进程(读进程或写进程)同时访问共享数据时则可能导致数据不一致的错误。因此要求:①允许多个读者可以同时对文件执行读操作;②只允许一个写者往文件中写信息;③任一写者在完成写操作之前不允许其他读者或写者工作;④写者执行写操作前,应让已有的读者和写者全部退出。

(二) 问题分析

与消费者进程不同,读者进程在读数据后并不会将数据清空,并不会改变数据。因此多个读者可同时访问共享数据。读进程与写进程同时共享数据,可能导致读出的数据不一致的问题。两个写进程同时共享数据,可能导致数据错误覆盖的问题
两类进程:写进程、读进程
互斥关系:写进程—写进程、写进程—读进程。读进程与读进程不存在互斥问题。
写者竞争和任何进程都互

1. 目的: 调试、修改、运行模拟程序,通过形象化的状态显示,使学生理解进程的概念,了解同步和通信的过程,掌握进程通信和同步的机制,特别是利用缓冲区进行同步和通信的过程。通过补充新功能,使学生能灵活运用相关知识,培养创新能力。 2. 内容及要求: 1) 调试、运行模拟程序。 2) 发现并修改程序中不完善的地方。 3) 修改程序,使用随机数控制创建生产者和消费者的过程。 4) 在原来程序的基础上,加入缓冲区的写互斥控制功能,模拟多个进程存取一个公共缓冲区,当有进程正在写缓冲区时,其他要访问该缓冲区的进程必须等待,当有进程正在读取缓冲区时,其他要求读取的进程可以访问,而要求写的进程应该等待。 5) 完成1)、2)、3)功能的,得基本分,完成4)功能的加2分,有其它功能改进的再加2分 3. 程序说明:   本程序是模拟两个进程,生产者(producer)和消费者(Consumer)工作。生产者每次产生一个数据,送入缓冲区中。消费者每次从缓冲区中取走一个数据。缓冲区可以容纳8个数据。因为缓冲区是有限的,因此当其满了时生产者进程应该等待,而空时,消费者进程应该等待;当生产者向缓冲区放入了一个数据,应唤醒正在等待的消费者进程,同样,当消费者取走一个数据后,应唤醒正在等待的生产者进程。就是生产者和消费者之间的同步。   每次写入和读出数据时,都将读和写指针加一。当读写指针同样时,又一起退回起点。当写指针指向最后时,生产者就等待。当读指针为零时,再次要读取的消费者也应该等待。 为简单起见,每次产生的数据为0-99的整数,从0开始,顺序递增。两个进程的调度是通过运行者使用键盘来实现的。 4. 程序使用的数据结构 进程控制块:包括进程名,进程状态和执行次数。 缓冲区:一个整数数组。 缓冲区说明块:包括类型,读指针,写指针,读等待指针和写等待指针。 5. 程序使用说明   启动程序后,如果使用'p'键则运行一次生产者进程,使用'c'键则运行一次消费者进程。通过屏幕可以观察到两个进程的状态和缓冲区变化的情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值