经典同步问题(哲学家进餐等)PPT教学课件
哲学家进餐问题

哲学家进餐问题问题描述:有5个哲学家共用一张圆桌,分别坐在周围的5张椅子上。
在桌上有5支筷子和5个碗,他们的生活方式是交替的进行思考和进餐。
平时,一个哲学家进行思考,饥饿时便试图取用他左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。
进餐完毕放下筷子继续思考。
解决方法:1)至多只允许4位哲学家同时去拿他左边的筷子,最终能保证至少有一个哲学家能够进餐,并在用毕时能够释放他用过的两支筷子,从而使更多的哲学家能够进餐。
2)规定奇数号哲学家先拿他左边的筷子然后再拿右边的筷子;而偶数号哲学家则与此相反。
3)仅当哲学家的左右两边的筷子都能用时才允许他拿起筷子进餐。
用第3)种方法解决代码如下:#include <stdio.h>#include <stdlib.h>#include <windows.h>#include <time.h>#define PHILOSOPHERS 5HANDLE gchopStick[PHILOSOPHERS];DWORD WINAPI PhilosopherThread(LPVOID pVoid) {HANDLE myChopsticks[2];DWORD result;int iPhilosopher = (int) pVoid;int iLeftChopstick = iPhilosopher;int iRightChopstick = iLeftChopstick + 1;if (iRightChopstick > PHILOSOPHERS-1)iRightChopstick = 0;myChopsticks[0] = gchopStick[iLeftChopstick];myChopsticks[1] = gchopStick[iRightChopstick];result=WaitForMultipleObjects(2,myChopsticks,TR UE,-1);printf("the %d PHILOSOPHER begin to eat\n",iPhilosopher);Sleep(200);printf("the %d PHILOSOPHER finishedeating",iPhilosopher);ReleaseMutex(myChopsticks[0]);ReleaseMutex(myChopsticks[1]);return EXIT_SUCCESS;}int main(int argc,char *argv[]){DWORD dwThreadId,wait_for_all;HANDLE hThread[PHILOSOPHERS];for (int i=0; i < PHILOSOPHERS; i++){gchopStick[i] = CreateMutex(NULL, FALSE, NULL);}for (i = 0; i < PHILOSOPHERS; i++)hThread[i] = CreateThread(NULL, 0, PhilosopherThread, (LPVOID) i, 0, &dwThreadId);wait_for_all=WaitForMultipleObjects(PHILOSOPHER S,hThread,TRUE,-1);printf("All PHILOSOPHERs finished eating\n");return 0; }。
经典进程同步问题

一、利用记录型信号量
解决哲学家进餐问题
假设每一位哲学家拿筷子的方法都是:先 拿起左边的筷子,再拿起右边的筷子,则第i 位哲学家的活动可描述为:
20
第i位哲学家的活动可描述为: repeat wait(chopstick[i]); wait(chopstick[i+1] mod 5); …. eat; …. signal(chopstick[i]); signal(chopstick[i+1] mod 5); …. think; until false;
full:=full - 1; if full <0 then block; mutex:=mutex-1; if mutex<0 then block; mutex:=mutex+1; if mutex<=0 then wakeup; empty:=empty+1; if empty<=0 then wakeup;
9
Wait操作不能颠倒!! P:wait(empty) wait(mutex)
C:wait(full) wait(mutex)
如果颠倒 P:wait(mutex) mutexl.value=0 wait(empty) 如果此时缓冲池满empty=-1,P阻塞 C:wait(mutex) mutex.value=-1, C阻塞 wait(full) P阻塞在empty队列中,等待一个空缓冲 C阻塞在mutex队列中,等待公共缓冲池访问权
6
consumer://消费者进程 begin repeat wait(full); wait(mutex); nextc:=buffer[out]; out∶=(out+1) mod n; signal(mutex); signal(empty); 消费这件产品; until false; end
经典同步问题(哲学家进餐等)

课堂习题
三个进程P1,P2,P3协作解决文件打 印问题,P1将文件记录从磁盘读入内存的 缓冲区1,每执行一次读一个记录;P2将缓 冲区1的内容取出放到缓冲区2中;P3将缓 冲区2的内容打印出来,每执行一次打印一 个记录。缓冲区的大小和一个记录大小一 样。 用P、V操作来保证文件的正确打印。
显然: 多个读者可同时读一个共享对象; 不允许一个写者与读者同时访问共享对象; 也不允许多个写者同时访问共享对象。
哲学家5号
5
无论4号5号谁 得到4号筷子,都 有一个可以进餐
2 哲学家3号
4
而5号没有人 与他竞争,得 若4号在与3号的竞 到左边的筷 争中没有得到筷子, 子 则5号得到4号筷子, 进餐
若4号在与3号 的竞争中得到 哲学家4号 筷子,则与5号 竞争4号筷子.
问题提出
某数据库有一个写进程、多个读进程, 它们之间读、写操作的互斥要求是:写进 程运行时,其他读、写进程不能对数据库 进行操作。读进程之间不互斥,可以同时 读数据库。请用信号量及PV操作描述这一 组进程的工作过程。
问题分析
同步问题描述: ● 当缓存满时,生产者必须等消费者从缓 存取走产品。设同步信号量为empty,其 初值为?。 ● 当缓存空时,消费者必须等生产者 放产品至缓存。设同步信号量为full,其初 值为?。
问题分析
互斥问题描述: ● 将有界缓存视为临界资源。由于两个进 程都要访问缓冲区,但是无论是生产者进 程向缓冲区放入产品,还是消费者进程从 缓冲区取走产品,都不能同时进行。所以, 两个进程访问缓冲区必须互斥地执行。 ● 设互斥信号量mutex的初始值为1, 以实现两进程对缓冲区访问的互斥。
问题分析
所以,为了实现生产者进程和消费者进 程的同步与互斥,设置三个信号量: 两个同步信号量empty和full, 一个互斥信号量mutex, 并在这三个信号量上施加正确的P、V 操作,就可保障两进程正确无误地运行。
哲学家就餐问题

哲学家就餐问题哲学家就餐问题模拟数学与计算机学院课程设计说明书课程名称: 操作系统原理-课程设计课程代码: 8404061题目: 哲学家就餐问题模拟年级/专业/班: 09级信息与计算科学三班学生姓名: 徐磊学号: 312009********* 开始时间: 2012 年 05 月 14 日完成时间: 2012 年 05月 31 日课程设计成绩:学习态度及平时成绩(30)技术水平与实际能力(20)创新(5)说明书撰写质量(45)总分(100)指导教师签名:年月日哲学家就餐问题模拟I 目录1 引言................................................. 错误!未定义书签。
1.1问题的提出 ................................................................................... 错误!未定义书签。
1.2任务与分析........................................................................................ 错误!未定义书签。
2.总体设计思想及相关知识.............................. 错误!未定义书签。
2.1总体设计思想 ......................................... 错误!未定义书签。
2.2临界区互斥编程原理........................................................................ 错误!未定义书签。
3 程序运行平台........................................... 错误!未定义书签。
4 程序类的说明........................................... 错误!未定义书签。
哲学家进餐问题-3中解决方案

哲学家进餐问题-3中解决⽅案问题描述⼀张圆桌上坐着5名哲学家,每两个哲学家之间的桌上摆⼀根筷⼦,桌⼦的中间是⼀碗⽶饭,如图2-10所⽰。
哲学家们倾注毕⽣精⼒⽤于思考和进餐,哲学家在思考时,并不影响他⼈。
只有当哲学家饥饿的时候,才试图拿起左、右两根筷⼦(⼀根⼀根地拿起)。
如果筷⼦已在他⼈⼿上,则需等待。
饥饿的哲学家只有同时拿到了两根筷⼦才可以开始进餐,当进餐完毕后,放下筷⼦继续思考。
问题分析1) 关系分析。
5名哲学家与左右邻居对其中间筷⼦的访问是互斥关系。
2) 整理思路。
显然这⾥有五个进程。
本题的关键是如何让⼀个哲学家拿到左右两个筷⼦⽽不造成死锁或者饥饿现象。
那么解决⽅法有两个,⼀个是让他们同时拿两个筷⼦;⼆是对每个哲学家的动作制定规则,避免饥饿或者死锁现象的发⽣。
⼀共5个哲学家,编号0 ~4, 5⽀筷⼦编号也是0 ~4, 0号哲学家右⼿的筷⼦编号是0号,逆时针增加,哲学家的编号也是逆时针增加所以:0号哲学家对应的是: 4号和1号筷⼦.1号哲学家对应的是: 0号和2号筷⼦.2号哲学家对应的是: 1号和3号筷⼦.3号哲学家对应的是: 2号和4号筷⼦.4号哲学家对应的是: 3号和0号筷⼦.所以有宏定义:#define left(phi_id) (phi_id+N-1)%N#define right(phi_id) (phi_id+1)%NN = 55⽀筷⼦对应5个互斥锁,所以:pthread_mutex_t forks[N]={PTHREAD_MUTEX_INITIALIZER};哲学家线程需要执⾏的动作是:void take_forks(int id){//获取左右两边的筷⼦printf("Pil[%d], left[%d], right[%d]\n", id, left(id), right(id));pthread_mutex_lock(&forks[left(id)]);pthread_mutex_lock(&forks[right(id)]);//printf("philosopher[%d] take_forks...\n", id);}void put_down_forks(int id){printf("philosopher[%d] is put_down_forks...\n", id);pthread_mutex_unlock(&forks[left(id)]);pthread_mutex_unlock(&forks[right(id)]);}void* philosopher_work(void *arg){int id = *(int*)arg;printf("philosopher init [%d] \n", id);while(1){thinking(id);take_forks(id);eating(id);put_down_forks(id);}}该算法存在以下问题:当五个哲学家都想要进餐,分别拿起他们左边筷⼦的时候(都恰好执⾏完pthread_mutex_unlock(&forks[left(id)]);)筷⼦已经被拿光了,等到他们再想拿右边的筷⼦的时候(执⾏pthread_mutex_unlock(&forks[right(id)]);)就全被阻塞了,这就出现了死锁。
哲学家进餐问题

死锁避免算法要求哲学家在取餐时按照固定的方向(顺时针或逆时针)进行。这 样,每个哲学家都只能等待其左侧或右侧的哲学家完成进餐后才能开始进餐。通 过这种方式,可以确保不会出现循环等待的情况,从而避免死锁的发生。
算法二:资源分级算法
总结词
资源分级算法通过优先满足更高级别的资源请求,避免死锁 的发生。
它被用来探讨多线程或多进程同步时可能出现的资源竞争和死锁情况。
问题的重要性
01
哲学家进餐问题是并发计算领域中的一个经典问题 ,对理解并发控制和同步机制至关重要。
02
解决哲学家进餐问题有助于避免死锁和资源竞争, 提高并发系统的可靠性和效率。
03
该问题还促进了并发算法和同步机制的研究,推动 了计算机科学的发展。
THANKS FOR WATCHING
感谢您的观看
哲学家进餐问题被视为并发控制领域的经典问题,它揭示了在并 发系统中资源访问冲突和死锁的可能性。
资源分配
该问题引发了对资源分配策略的深入研究,如何合理地分配资源以 避免冲突和死锁,成为计算机科学领域的重要议题。
算法设计
哲学家进餐问题为算法设计提供了一种挑战性的场景,促使研究者 设计出更高效、安全的并发算法和协议。
哲学家进餐问题
汇报人: 202X-01-05
contents
目录
• 问题的背景和起源 • 问题描述和模型建立 • 解决方案和算法 • 问题的影响和启示 • 问题的发展和未来方向
01
问题的背景和起源
问题的起源
哲学家进餐问题源于计算机科学和数学的交叉领域,特别是并发计算和同步问题。
该问题由艾兹赫尔·戴克斯特拉在1965年首次提出,旨在解决并发控制中的死锁问题 。
进程同步与互斥_哲学家进餐问题

2.1总体设计思想
哲学家的生活就是思考和吃饭,即思考,饿了就吃,吃饱了再思考,循环往复。要求是:每一个哲学家只有在拿到位于他左右两侧的筷子后,才能够就餐;哲学家不能拿着一只筷子不放手,也不能从其他哲学家手中抢夺筷子;哲学家每次吃饱后必须放下他手中的两只筷子恢复思考,不能强抓住筷子不放。
设计一个程序,能够显示当前各哲学家的状态和桌上筷子的使用情况,并能无死锁的推算出下一状态各哲学家的状态和桌上筷子的使用情况。即设计一个能安排哲学家正常生活的程序。
4
using System;
using System.Collections.Generic;
using ponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
3.退出区:清除临界区被占用的标志
4.剩余区:进程与临界区不相关部分的代码
2.2系,是为完成某种任务而建立的两个或多个线程,这个线程需要在某些位置上协调他们的工作次序而等待、传递信息所产生的制约关系。进程间的直接制约关系来源于他们之间的合作。
比如说进程A需要从缓冲区读取进程B产生的信息,当缓冲区为空时,进程B因为读取不到信息而被阻塞。而当进程A产生信息放入缓冲区时,进程B才会被唤醒。概念如下图所示。
for (int i = 0; i < 5; i++)
{
pts = new ParameterizedThreadStart(Eating);
m_thread[i] = new Thread(pts);
}
Philospher ph = new Philospher();
4.10经典进程互斥同步问题:哲学家进餐问题

4.10经典进程互斥同步问题:哲学家进餐问题(the dining philosophers problem)问题描述:(由Dijkstra首先提出并解决)5个哲学家围绕一张圆桌而坐,桌子上放着5支筷子,每两个哲学家之间放一支,哲学家的动作包括思考和进餐,进餐时需要同时拿起他左边和右边的两支筷子,思考时则同时将两支筷子放回原处。
要考虑的问题是如何保证哲学家们的动作有序进行?如:不出现相邻者同时要求进餐;不出现有人永远拿不到筷子。
在这里,哲学家的生活规律是:Repeat思考;取fork[i];取fork[(i+1) mod 5];进食;放fork[i];放fork[(i+1) mod 5];Until false;实现方法:一个信号量表示一根筷子,五个信号量构成信号量数组chop[5],所有信号量初始值为1。
第i个哲学家的进餐过程为:思考问题P(chop[i]);P(chop(i+1) mod 5]);进餐V(chop[i]);V(chop[(i+1) mod 5]);该算法可保证两个相邻的哲学家不能同时进餐,但不能防止五位哲学家同时拿起各自左边的筷子、又试图拿起右边的筷子,这会引起死锁。
这里给出可以防止死锁发生的一种解决方案:Semaphore fork[5] = {1};Semaphore room = 4;Void philospher (int i) {while (true) {thinking();P( room );P(fork[i]);P(fork[(i+1) mod 5])eating();V(fork[i]);V(fork[(i+1) mod 5])V(room); }。
哲学家进餐问题(操作系统)

哲学家进餐问题(操作系统)哲学家进餐问题(操作系统)1.简介1.1 背景介绍哲学家进餐问题是计算机科学中一个经典的并发问题,最早由Edsger Dijkstra在1965年提出。
1.2 问题描述问题的场景是五位哲学家围坐在一张圆桌前,每个哲学家面前有一碗饭和一根筷子。
哲学家需要交替地思考和进餐,但是他们只能使用左右两边的筷子来进餐。
1.3 目标设计一个算法来保证哲学家们能够交替地进餐,同时避免死锁和饥饿现象的发生。
2.解决方案2.1 简单解法一个简单的解法是给每个哲学家编号,规定奇数号哲学家先拿左边的筷子,偶数号哲学家先拿右边的筷子。
当一个哲学家需要拿筷子时,他会先检查他的两边是否有其他哲学家正在使用,如果没有,他就可以拿起两边的筷子进餐。
否则,他需要等待直到两边的筷子都可用。
2.2 改进解法上述简单解法可能会导致死锁问题。
为了避免死锁,我们可以引入资源分级的概念。
每个筷子被分为两个等级,分别是主要资源和次要资源。
哲学家需要按照顺序来获取资源,例如,先获取主要资源,然后获取次要资源。
3.算法实现3.1 数据结构我们可以使用一个数组来表示圆桌上的五个筷子,同时使用一个锁数组来表示每个筷子的状态(是否被占用)。
3.2 算法流程在哲学家进餐问题中,每个哲学家都需要经历思考和进餐两个过程,我们可以使用线程来模拟这两个过程。
4.算法分析4.1 死锁问题通过引入资源分级的概念,我们成功避免了死锁问题的发生。
每个哲学家按照顺序获取资源,不会出现他们都在等待同一个资源的情况。
4.2 饥饿问题在我们的算法中,每个哲学家都会交替地进餐和思考,因此不会出现饥饿问题。
5.附件本文档暂无附件。
6.法律名词及注释6.1 死锁死锁是指在并发系统中,两个或多个进程或线程无限期地互相等待对方所占有的资源的情形。
6.2 饥饿饥饿是指某个进程或线程因无法获得所需的资源而无法继续执行的情况。
进程管理四经典进程同步问题

1. AND型信号量集
AND型信号量集用于同时需要多种资源且每种占用一个时的信 号量操作; • 问题:一段处理代码需要同时获取两个或多个临界资源―― 可能死锁:各进程分别获得部分临界资源,然后等待其余的 临界资源,"各不相让" • 解决方法:在一个wait原语中,将一段代码同时需要的多个 临界资源,要么全部分配给它,要么一个都不分配。称为 Swait(Simultaneous Wait)。 • 在Swait时,各个信号量的次序并不重要,虽然会影响进程归 入哪个阻塞队列。由于是对资源全部分配或不分配,所以总 有进程获得全部资源并在推进之后释放资源,因此不会死锁。
怎样判断有没有读者在读?
增加一个公共变量Readcount,表示当前有 几个读者进程在读。
新来一个读者进程,Readcount加1; 撤销一个读者进程,Readcount减1; 第一个读者:阻塞所有写者进程;允许其他读者进程执行。 最后一个读者:唤醒可能的写者进程。 Readcount成为临界资源,必须互斥访问: 增加互斥信号量Rmutex
需要注意: 原先处于阻塞状态的进程,被唤醒后,从何处开始执行? 与 记录型信号量机制有何不同?
15
生产者-消费者问题 - AND型信号量机制
• 若不愿意考虑wait操作的先后顺序,也可用AND型信号 量来实现。 • 生产者进程中: – 用Swait(empty,mutex)代替wait(empty)和wait(mutex), – 用Ssignal(mutex,full)代替signal(mutex)和signal(full) • 消费者进程中 – 用Swait(full,mutex)代替wait(full)和wait(mutex), – 用Ssignal(mutex,empty)代替signal(mutex)和 signal(empty)
哲学家进餐问题

一、需求分析有一个故事是这样的:假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。
吃东西的时候,他们就停止思考,思考的时候也停止吃东西。
餐桌中间有一大碗意大利面,每两个哲学家之间有一只餐叉。
因为用一只餐叉很难吃到意大利面,所以假设哲学家必须用两只餐叉吃东西。
他们只能使用自己左右手边的那两只餐叉。
上边的故事里有五个哲学家(不过我们写的程序可以有N个哲学家),这些哲学家们只思考或吃饭,他们思考的时候不需要任何共享资源,但是吃饭的时候就必须使用餐具,而餐桌上的餐具是有限的,故事里,餐具是叉子,吃饭的时候要用两把叉子把面条从碗里捞出来。
很显然把叉子换成筷子会更合理,因为一个哲学家需要两根筷子才能吃饭。
现在引入问题:有六个哲学家很穷,只买得起六根筷子。
他们坐成一圈,两个人的中间放一根筷子。
哲学家吃饭的时候必须同时得到左手边和右手边的筷子。
如果他身边的任何一位正在使用筷子,那他只有等着。
如下图:AA 4 A1、2、3、4、5、6为哲学家A为一根筷子以上就为我们要处理的哲学家就餐问题,接下来将编写程序模拟解决这个问题。
二、系统概要设计2.1设计一个程序,能够显示当前各哲学家的状态和桌上餐具的使用情况,并能无死锁的推算出一状态各哲学家的状态和桌上餐具的使用情况。
即设计一个能安排哲学家正常生活的程序。
为哲学家设计3种状态,即“等待”“进餐”“思考”。
每个哲学家重复进行“等待”->“进餐”->“思考”的行动循环。
其中:“等待”->“进餐”:只有一个哲学家处于等待进餐状态,且左右手两边的餐具都处于“空闲”状态时,可以发生这种状态改变。
此状态改变发生后,哲学家拿起左右手两边的餐具。
“进餐”->“思考”:此状态改变发生后,哲学家放下左右手上的餐具。
餐具状态由“使用中”转变为“空闲”。
“思考”->“等待”:哲学家思考结束后,无条件转入等待状态。
由上所述,程序中应设置6个元素的信号量数组用来保持哲学家之间的同步。
哲学家就餐问题解释

哲学家就餐问题是在计算机科学中的一个经典问题,用来演示在并行计算中多线程同步(Synchronization)时产生的问题。
在1971年,著名的计算机科学家艾兹格·迪科斯彻提出了一个同步问题,即假设有五台计算机都试图访问五份共享的磁带驱动器。
稍后,这个问题被托尼·霍尔重新表述为哲学家就餐问题。
这个问题可以用来解释死锁和资源耗尽。
哲学家就餐问题可以这样表述,假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。
吃东西的时候,他们就停止思考,思考的时候也停止吃东西。
餐桌中间有一大碗意大利面,每两个哲学家之间有一只餐叉。
因为用一只餐叉很难吃到意大利面,所以假设哲学家必须用两只餐叉吃东西。
他们只能使用自己左右手边的那两只餐叉。
哲学家就餐问题有时也用米饭和筷子而不是意大利面和餐叉来描述,因为很明显,吃米饭必须用两根筷子。
哲学家从来不交谈,这就很危险,可能产生死锁,每个哲学家都拿着左手的餐叉,永远都在等右边的餐叉(或者相反)。
即使没有死锁,也有可能发生资源耗尽。
例如,假设规定当哲学家等待另一只餐叉超过五分钟后就放下自己手里的那一只餐叉,并且再等五分钟后进行下一次尝试。
这个策略消除了死锁(系统总会进入到下一个状态),但仍然有可能发生“活锁”。
如果五位哲学家在完全相同的时刻进入餐厅,并同时拿起左边的餐叉,那么这些哲学家就会等待五分钟,同时放下手中的餐叉,再等五分钟,又同时拿起这些餐叉。
在实际的计算机问题中,缺乏餐叉可以类比为缺乏共享资源。
一种常用的计算机技术是资源加锁,用来保证在某个时刻,资源只能被一个程序或一段代码访问。
当一个程序想要使用的资源已经被另一个程序锁定,它就等待资源解锁。
当多个程序涉及到加锁的资源时,在某些情况下就有可能发生死锁。
例如,某个程序需要访问两个文件,当两个这样的程序各锁了一个文件,那它们都在等待对方解锁另一个文件,而这永远不会发生。
[编辑]服务生解法一个简单的解法是引入一个餐厅服务生,哲学家必须经过他的允许才能拿起餐叉。
操作系统(哲学家进餐问题)

操作系统(哲学家进餐问题)哲学家进餐问题:有五个哲学家,他们的⽣活⽅式是交替地进⾏思考和进餐。
哲学家们共⽤⼀张园桌,分别坐在周围五张椅⼦上。
在圆桌上五⽀筷⼦,平时⼀个哲学家进⾏思考,饥饿时便试图取⽤其左右最靠近他的筷⼦,只有在他拿到两⽀筷⼦时才能进餐。
进程毕,放下筷⼦⼜继续思考。
问题分析:筷⼦是临界资源,⼀次只能被⼀个哲学家使⽤。
因此,五个⼈不能同时拿起左边的筷⼦(或右边)否则或引起死锁。
解决⽅案:(1)⾄多只允许四位哲学家同时拿左边的筷⼦,最终保证有⼀位哲学家能够进餐,并且⽤完能够释放筷⼦,让更多的哲学家进餐。
(2)仅当哲学家左右两只筷⼦都可以⽤的时候,才允许拿筷⼦进餐。
semaphore chopstick[5]={1,1,1,1,1};//五个信号量,⼀个信号量代表⼀只筷⼦semaphore mutex=1;Pi(){while(1){wait(mutex);//设置信号量,防⽌其它⼈争夺资源wait(chopstick[i]);wait(chopstick[(i+1)%5]);signal(mutex);//拿到两只筷⼦后释放信号量吃饭;signal(chopstick[i]);//吃过饭后,释放筷⼦资源signal(chopstick[(i+1)%5]);}}(3)奇数号哲学家先拿左边的,再拿右边的;偶数则相反。
即五位哲学家都先竞争奇数号筷⼦,获得后再去竞争偶数号筷⼦,最终总会有⼀位哲学家有两只筷⼦。
semaphore chopstick[5]={1,1,1,1,1};Pi(){while(1){if(i%2!=0){//奇数号哲学家wait(chopstick[i]);//拿左边的wait(chopstick[(i+1)%5]);//右边的}else{//偶数号哲学家wait(chopstick[(i+1)%5]);//右边的wait(chopstick[i]);//左边的}进餐;signal(chopstick[i]);//释放筷⼦资源signal(chopstick[(i+1)%5]);}}。
《哲学家进餐问题操作系统》课件模板

signal (fork[ i + 1 ] mod 5) ;
signal (fork[ i]) ;
}
Else
//奇数哲学家,先左后右。
{
wait (fork[ i]) ;
wait (fork[ i + 1 ] mod 5) ;
eat();
signal (fork[ i]) ;
signal (fork[ i + 1 ] mod 5) ;
算法改善:
至多只允许四个哲学家同时进餐,以保 证至少有一个哲学家能够进餐,最终总会释 放出他所使用过的两支筷子,从而可使更多 的哲学家进餐。
改进后的算法A
semaphore fork[5]={1,1,1,1,1};
semaphore room=4;
void philosopher(int i)
{
算法 A
void philosopher(int i) /*i:哲学家编号,从0 到4*/
{
while (TRUE)
{
think( );
/*哲学家正在思考*/
take_fork(i);
/*取左侧的筷子*/
take_fork((i+1) % N); /*取右侧筷子;%为取模运算*/
eat( );
/*吃饭*/
哲学家进餐问题操作系统
(Excellent handout training template)
问题描述
设有五个哲学家,共用一张放有五把椅子 的餐桌,每人坐在一把椅子上,桌子上有五个 碗和五只筷子,每人两边各放一只筷子。哲学 家们是交替思考和进餐,饥饿时便试图取其左 右最靠近他的筷子。
0 1
4
3
哲学家就餐

• signal(chopstick[(i+1)]mod5); • singal(chopstick[i]); •} • else •{ • Wait(chopsticl[i]); • Wait(chopstick[i+1]mod5); • eat(); • singal(chopstick[i]); • signal(chopstick[(i+1)]mod5); •} •}
• 所有信号量均被初始化为1 ,第i 位哲学家的活动课描述为:
• repeat: • wait(chopstick[i]); • Wait(chopstick[(i+1)mod5); •… • eat; •… • signal(chopstick[i]); • signal(chopstick([i+1]mod5); •… • Think; • until false
五个人五只筷子该如何进行用餐啊
利用记录型信号量解决:
• 进分析可知,放在桌子上 的筷子是临界资源,在一 段时间内允许一位哲学家 使用。为了实现对筷子的 互斥使用,可以用一个信 号量表示一只筷子,由这 五个信号量构成信号量数 组。其描述如下:
• Var chopstick:array[0,…,4]of semaphore;
• Thinking[i] = 1;
•
•}
• time = 0;
•
• for(;n<=meat;)
•{
• ++time;
• printf("=================这是第 %d秒的开始 ==================\n",time);
• eat();
• thinking();
哲学家就餐问题

管程机制
1. 管程可以看做一个软件模块,它是将共享 的变量和对于这些共享变量的操作封装起 来,形成一个具有一定接口的功能模块, 进程可以调用管程来实现进程级别的并发 控制。 2. 进程只能互斥的使用管程,即当一个进程 使用管程时,另一个进程必须等待,当一 个进程使用完管程后,它必须释放管程并 唤醒等待管程的另一个管程。
一、哲学家就餐问题与C语言:
• 死锁问题
• 其实呢,这个问题在我们计算机中也经常遇到, 用户需要的特定信息由几部分组成,而几个用户 各掌握了特定信息的一部分,彼此不放手,导致 持续的等待我们称之为死锁。在我们学习了哲学 家就餐问题之后,我们可以轻松地解决这个问题
死锁问题解决方法:
(1)至多只允许四个哲学家同时进餐,以保证至少有一个哲学家 能够进餐,最终总会释放出他所使用过的两支筷子,从而可 使更多的哲学家进餐. (2)仅当哲学家的左右两支筷子都可用时,才允许他拿起筷子 进餐. (3)规定奇数号的哲学家先拿起他左边的筷子,然后再去拿他 右边的筷子;而偶数号的哲学家则相反.按此规定,将是1,2号 哲学家竞争1号筷子,3,4号哲学家竞争3号筷子.即五个哲学 家都竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总 会有一个哲学家能获得两支筷子而进餐.
Chandy/Misra解法
• 1984年,K. Mani Chandy和J. Misra提出了哲学家就餐问题的另一个解 法,允许任意的用户(编号P1, ..., Pn)争用任意数量的资源。与迪科 斯彻的解法不同的是[来源请求],这里编号可以是任意的。 • 1.对每一对竞争一个资源的哲学家,新拿一个餐叉,给编号较低的哲 学家。每只餐叉都是“干净的”或者“脏的”。最初,所有的餐叉都 是脏的。 • 2.当一位哲学家要使用资源(也就是要吃东西)时,他必须从与他竞 争的邻居那里得到。对每只他当前没有的餐叉,他都发送一个请求。 • 3.当拥有餐叉的哲学家收到请求时,如果餐叉是干净的,那么他继续 留着,否则就擦干净并交出餐叉。 • 4.当某个哲学家吃东西后,他的餐叉就变脏了。如果另一个哲学家之 前请求过其中的餐叉,那他就擦干净并交出餐叉。 • 这个解法允许很大的并行性,适用于任意大的问题。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
哲学家2号
此时5号条件满 足,可在下一时 钟周期拿左筷子
哲学家5号
此时4号条件 不再满足,放
下筷子.
2020/12/12
3号开始进餐, 同时1号放下 右边的筷子
哲学家3号
哲学家4号
1号放下左边筷
子的同时,3号
可拿起右边筷
子
18
哲学家1号
哲学家2号
这种方法将出现1,2
号哲学家单键1号筷
子,3,4号哲学家竞争
2020/12/12
1
模型分析
• (1)生产者进行生产将物品放入仓库,同一时 间只能有一个生产者将物品放入仓库,若仓库满, 生产者将等待;
• (2)消费者从仓库中取出物品,同一时间只能 有一个消费者取出物品,若仓库空,消费者等待;
• (3)生产者将物品放入仓库时消费者不能同时 取;
• (4)消费者取物品时生产者不能放入物品。
20
问题提出
某数据库有一个写进程、多个读进程, 它们之间读、写操作的互斥要求是:写进 程运行时,其他读、写进程不能对数据库 进行操作。读进程之间不互斥,可以同时 读数据库。请用信号量及PV操作描述这一 组进程的工作过程。
2020/12/12
21
问题分析
本题涉及对同一个数据库的读写操作。当多个 进程对其读时,因不改变其中的数值,可以不加 限制。当既有的读进程,又有写进程时,应加以 限制。此时,数据库就是一个临界资源,读写进 程必须对其进行互斥操作。
何?
2020/12/12
6
应注意的问题(总结)
(1) 在每个程序中必须先做P(mutex) 后做V(mutex),二者要成对出现。
(2) 对同步信号量full和empty的P、V 操作同样必须成对出现,但它们分别位于 不同进程的代码中。
(3) 无论在生产者进程中还是在消费者 进程中,两个P操作的次序都不能颠倒。应 先执行同步信号量的P操作,再执行互斥信 号量的P操作;否则可能造成进程死锁
• (1)至多只允许有4位哲学家同时去拿左边的筷 子,最终能保证至少有一位哲学家能够进餐,并 在用毕时能释放出他用过的两只筷子,从而使更 多的哲学家能够进餐。
• (2)仅当哲学家的左、右两只筷子均可用时,才 允许他拿起筷子进餐。
• (3)规定奇数号哲学家先拿他左边的筷子,然后 再去拿右边的筷子;而偶数号哲学家则相反。最 后总会有一位哲学家能获得两只筷子而进餐。
每个哲学家或思考问题或就餐,当思考 问题时放下筷子,饥饿的时候就吃菜。
想要夹菜时必须获得两根筷子,且每人 只能从自己的左边和右边去取筷子,只有 在他拿到两只筷子时才能进餐。就餐后放 下筷子以供别人使用,自己继续思考问题。
2020/12/12
13
哲学家 筷子 盘子
哲学家5号
2020/12/12
9
问题分析和解题步骤
• (1)确定进程的 个数及其工作内容
2020/12/12
10
解题步骤
• (2)确定互斥信号量的个数、含义 • (3)用P、V操作描述关系
2020/12/12
11
2020/12/12
12
问题提出
有5个哲学家他们围坐在一张圆桌旁,每 人面前有一菜盘,各菜盘之间有一根筷子。
22
解题步骤
• (1)确定进程的个数及工作。本题只有读写两类进程, 各自的工作如图所示。
• (2)确定信号量的个数、含义及PV操作。
2020/12/12
2
问题分析
同步问题描述: ● 当缓存满时,生产者必须等消费者从缓 存取走产品。设同步信号量为empty,其 初值为?。 ● 当缓存空时,消费者必须等生产者 放产品至缓存。设同步信号量为full,其初 值为?。
2020/12/12
3
问题分析
互斥问题描述: ● 将有界缓存视为临界资源。由于两个进 程都要访问缓冲区,但是无论是生产者进 程向缓冲区放入产品,还是消费者进程从 缓冲区取走产品,都不能同时进行。所以, 两个进程访问缓冲区必须互斥地执行。 ● 设互斥信号量mutex的初始值为1, 以实现两进程对缓冲区访问的互斥。
2020/12/12
16
1号哲学家 开始进餐,完 成后放下筷 子,其它哲学5 家开始进餐
哲学家5号
哲学家1号 1
哲学家2号 2
哲学家3号
4
此时5号哲学家被 禁止拿筷子.1号哲
学家拿起他右边即 2020/12/12 5号哲学家左边的
3 哲学家4号
17
设1号进餐,则 3,4两位哲学 家可以拿筷子
1号进餐完毕, 哲放学家下1号筷子,先
2020/12/12
7
2020/12/12
8
问题提出
设有4个哲学家围坐在一张圆桌前讨论 问题和进餐。在在讨论时每人手中什么都 不拿,当需要进餐时,每人需要用刀和叉 各一把。餐桌上的布置如图所示,共有两 把刀和两把叉,每把刀或叉供相邻的两个 人使用。
请用信号量及PV操作说明4位哲学家的 同步过程。
5
3号筷子的情况.
哲学家5号
4
而5号没有人
与他竞争,若得4号在与3号的竞 到左边的筷争中没有得到筷子, 2020/子12/12则5号得到4号筷子,
进餐
1
无论4号5号谁 得到4号筷子,都 有一个可以进餐
2 哲学家3号
若4号在与3号
的竞争中得到 哲学筷家4号子,则与5号
竞争4号筷子.
19
2020/12/12
因为写进程执行时,不能执行其他读写进程, 所以还必须设置一个计数器统计读进程的个数。 如果是第一个读进程,就与写进程竞争数据库。 如果是最后一个读进程,就释放数据库。因计数 器是一个临界资源,所以多个读进程对计数器的 操作又是互斥操作。
这是一个互斥问题,也是典型的读者和写者问题。
2020/12/12
哲学家2号
1
5
2 哲学家3号
4 3
哲学家4号
14
先拿左,拿到后再 拿右,成功后进餐. 吃完后先放左再放 右.虽可保证不会 有相邻的同时进餐, 但可能死锁,如动
画所示.
5
哲学家5号
哲学家1号 1
哲学家2号 2
哲学家3号
4
2020/12/12
哲学家4号
此时没有一个哲学 家可以完成进餐.
3
15
解决方法
2020/12/12
4
问题分析
所以,为了实现生产者进程和消费者进 程的同步与互斥,设置三个信号量:
两个同步信号量empty和full, 一个互斥信号量mutex,
并在这三个信号量上施加正确的P、V 操作,就可保障两进程正确无误地运行。
2020/12/12
5
思考
• (1)若将两个P操作互换位置,结果如何? • (2)若将两个V操作互换位置,结果又如