经典进程同步问题
1.生产者—消费者问题
如果一个进程能产生并释放资源,则该进程称做生产者;如果一个进程单纯使用(消耗)资源,则该进程称做消费者。
生产者-消费者问题表述如下:
一组生产者进程和一组消费者进程(设每组有多个进程)通过缓冲区发生联系。生产者进程将生产的产品(数据、消息等统称为产品)送入缓冲区,消费者进程从中取出产品。假定缓冲区共有N个,可把它们设想成一个环形缓冲池。
它们应满足如下同步条件:
① 任一时刻所有生产者存放产品的单元数不能超过缓冲区的总容量(N )。
② 所有消费者取出产品的总量不能超过所有生产者当前生产产品的总量。
在此问题中:
(1)
生产者之间要互斥使用缓冲区;
消费者之间要互斥使用缓冲区;
生产者、消费者之间要互斥使用缓冲区。
(2)
生产者、消费者之间有同步合作的关系。
1.设缓冲区的编号为0~N-1,in和out分别是生产者进程和消费者进程使用的指针,指向下面可用的缓冲区,初值都是0。
2.设置三个信号量:
full:表示放有产品的缓冲区数,其初值为0。
empty:表示可供使用的缓冲区数,其初值为N。
mutex:互斥信号量,初值为1,表示各进程互斥进入临界区,保证任何时候只有一个进程使用缓冲区。
2.读者—写者问题
读者-写者问题也是一个著名的进程互斥访问有限资源的问题。例如,一个航班预订系统有一个大型数据库,很多竞争进程要对它进行读、写。允许多个进程同时读该数据库,但是在任何时候如果有一个进程写(即修改)数据库,那么就不允许其他进程访问它—— 既不允许写,也不允许读。
设置两个信号量:读互斥信号量rmutex和写互斥信号量wmutex。另外设立一个读计数器readcount,它是一个整型变量,初值为0。
rmutex:用于读者互斥地访问readcount,初值为1。
wmutex:用于保证一个写者与其他读者/写者互斥地访问共享资源,初值为1。
以上算法是一种读者优先算法,即只要有一个读者正在读操作,它就可以保持对数据区的控制,这就易使写者饥饿。
该问题的另一个变种:写者优先算法,即只要写者申请写操作,就不允许新的读者访问数据区。该算法读者们可能饥饿。
3.哲学家进餐问题
五个哲学家围坐在一个圆桌周围,每个哲学家面前都有一只碗,各碗之间分别有一根筷子,餐桌如下图。
哲学家的生活包括两种活动:即吃面条和思考。当哲学家觉得饿时,他就分两次去取他左边和右边的筷子,每次拿一根(不能强行从邻座手中抢过筷子),如果成功,他就开始吃面条,吃完后把筷子放回原处继续思考。
初步分析:获得两根筷子时才可进餐。
哲学家进餐问题
筷子是临界资源,一段时间内只允许一个哲学家使用。可用一个信号量表示一根筷子。由五个信号量构成信号量数组。第i个哲学家的进餐过程可描述如下:
解决死锁的方法:
(1) 最多只允许4个哲学家同时拿筷子,保证有一人能 够进餐。
(2) 仅当左、右两根筷子均可用时,才允许他拿起筷子。
(3) 奇数号哲学家先拿左边的筷子,偶数号先拿右边的筷子。
方法(1)的算法描述如下:
4.打瞌睡的理发师问题
问题描述:理发店有一名理发师、一把理发椅和几把座椅,等待的理发者可以坐在座椅上。如果没有顾客到来,理发师就坐在理发椅上打盹。当顾客到来时,就唤醒理发师。如果顾客到来时理发师正在理发,该顾客就坐在椅子上排队;如果满座了,他就离开这个理发店,到别处理发。
利用信号量机制为理发师和顾客各编写一段程序,描述他们的行为。
打瞌睡的理发师问题示意图
分析其中的互斥和同步关系:
- 理发师和顾客是同步关系
- 椅子是临界资源,应互斥使用
理发师和每位顾客都分别是一个进程。
希望对你有帮助!加油!
若您认为本文内容有益,请不吝赐予赞同并订阅,以便持续接收有价值的信息。衷心感谢您的关注和支持!