哲学家进餐问题

哲学家进餐问题
哲学家进餐问题

1.哲学家进餐问题:

(1) 在什么情况下5 个哲学家全部吃不上饭?

考虑两种实现的方式,如下:

A.

算法描述:

void philosopher(int i) /*i:哲学家编号,从0 到4*/

{

while (TRUE) {

think( ); /*哲学家正在思考*/

take_fork(i); /*取左侧的筷子*/

take_fork((i+1) % N); /*取左侧筷子;%为取模运算*/

eat( ); /*吃饭*/

put_fork(i); /*把左侧筷子放回桌子*/

put_fork((i+1) % N); /*把右侧筷子放回桌子*/

}

}

分析:假如所有的哲学家都同时拿起左侧筷子,看到右侧筷子不可用,又都放下左侧筷子,

等一会儿,又同时拿起左侧筷子,如此这般,永远重复。对于这种情况,即所有的程序都在

无限期地运行,但是都无法取得任何进展,即出现饥饿,所有哲学家都吃不上饭。B.

算法描述:

规定在拿到左侧的筷子后,先检查右面的筷子是否可用。如果不可用,则先放下左侧筷子,

等一段时间再重复整个过程。

分析:当出现以下情形,在某一个瞬间,所有的哲学家都同时启动这个算法,拿起左侧的筷

子,而看到右侧筷子不可用,又都放下左侧筷子,等一会儿,又同时拿起左侧筷子……如此

这样永远重复下去。对于这种情况,所有的程序都在运行,但却无法取得进展,即出现饥饿,

所有的哲学家都吃不上饭。

(2) 描述一种没有人饿死(永远拿不到筷子)算法。

考虑了四种实现的方式(A、B、C、D):

A.原理:至多只允许四个哲学家同时进餐,以保证至少有一个哲学家能够进餐,最终总会释

放出他所使用过的两支筷子,从而可使更多的哲学家进餐。以下将room 作为信号量,只允

许4 个哲学家同时进入餐厅就餐,这样就能保证至少有一个哲学家可以就餐,而申请进入

餐厅的哲学家进入room 的等待队列,根据FIFO 的原则,总会进入到餐厅就餐,因此不会

出现饿死和死锁的现象。

伪码:

semaphore chopstick[5]={1,1,1,1,1};

semaphore room=4;

void philosopher(int i)

{

while(true)

{

think();

wait(room); //请求进入房间进餐

wait(chopstick[i]); //请求左手边的筷子

wait(chopstick[(i+1)%5]); //请求右手边的筷子

eat();

signal(chopstick[(i+1)%5]); //释放右手边的筷子

signal(chopstick[i]); //释放左手边的筷子

signal(room); //退出房间释放信号量room

}

}

B.原理:仅当哲学家的左右两支筷子都可用时,才允许他拿起筷子进餐。

方法1:利用AND 型信号量机制实现:根据课程讲述,在一个原语中,将一段代码同时需

要的多个临界资源,要么全部分配给它,要么一个都不分配,因此不会出现死锁的情形。当

某些资源不够时阻塞调用进程;由于等待队列的存在,使得对资源的请求满足FIFO 的要求,

因此不会出现饥饿的情形。

伪码:

semaphore chopstick[5]={1,1,1,1,1};

void philosopher(int I)

{

while(true)

{

think();

Swait(chopstick[(I+1)]%5,chopstick[I]);

eat();

Ssignal(chopstick[(I+1)]%5,chopstick[I]);

}

}

方法2:利用信号量的保护机制实现。通过信号量mutex对eat()之前的取左侧和右侧筷

子的操作进行保护,使之成为一个原子操作,这样可以防止死锁的出现。

伪码:

semaphore mutex = 1 ;

semaphore chopstick[5]={1,1,1,1,1};

void philosopher(int I)

while(true)

{

think();

wait(mutex);

wait(chopstick[(I+1)]%5);

wait(chopstick[I]);

signal(mutex);

eat();

signal(chopstick[(I+1)]%5);

signal(chopstick[I]);

}

}

C.原理:规定奇数号的哲学家先拿起他左边的筷子,然后再去拿他右边的筷子;而偶数号

的哲学家则相反.按此规定,将是1,2号哲学家竞争1号筷子,3,4号哲学家竞争3号筷子.即

五个哲学家都竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总会有一个哲学家能获

得两支筷子而进餐。而申请不到的哲学家进入阻塞等待队列,根FIFO原则,则先申请的哲

学家会较先可以吃饭,因此不会出现饿死的哲学家。

伪码:

semaphore chopstick[5]={1,1,1,1,1};

void philosopher(int i)

{

while(true)

{

think();

if(i%2 == 0) //偶数哲学家,先右后左。

{

wait (chopstick[ i + 1 ] mod 5) ;

wait (chopstick[ i]) ;

eat();

signal (chopstick[ i + 1 ] mod 5) ;

signal (chopstick[ i]) ;

}

Else //奇数哲学家,先左后右。

{

wait (chopstick[ i]) ;

wait (chopstick[ i + 1 ] mod 5) ;

eat();

signal (chopstick[ i]) ;

signal (chopstick[ i + 1 ] mod 5) ;

}

D.利用管程机制实现(最终该实现是失败的,见以下分析):

原理:不是对每只筷子设置信号量,而是对每个哲学家设置信号量。test()函数

有以下作

用:

a. 如果当前处理的哲学家处于饥饿状态且两侧哲学家不在吃饭状态,则当前哲

学家通过

test()函数试图进入吃饭状态。

b. 如果通过test()进入吃饭状态不成功,那么当前哲学家就在该信号量阻塞等待,直到

其他的哲学家进程通过test()将该哲学家的状态设置为EATING。

c. 当一个哲学家进程调用put_forks()放下筷子的时候,会通过test()测试它的邻居,

如果邻居处于饥饿状态,且该邻居的邻居不在吃饭状态,则该邻居进入吃饭状态。由上所述,该算法不会出现死锁,因为一个哲学家只有在两个邻座都不在进餐时,才允

许转换到进餐状态。

该算法会出现某个哲学家适终无法吃饭的情况,即当该哲学家的左右两个哲学家交替

处在吃饭的状态的时候,则该哲学家始终无法进入吃饭的状态,因此不满足题目的要求。

但是该算法能够实现对于任意多位哲学家的情况都能获得最大的并行度,因此具有重要

的意义。

伪码:

#define N 5 /* 哲学家人数*/

#define LEFT (i-1+N)%N /* i的左邻号码*/

#define RIGHT (i+1)%N /* i的右邻号码*/

typedef enum { THINKING, HUNGRY, EATING } phil_state; /*哲学家状态*/ monitor dp /*管程*/

{

phil_state state[N];

semaphore mutex =1;

semaphore s[N]; /*每个哲学家一个信号量,初始值为0*/

void test(int i)

{

if ( state[i] == HUNGRY &&state[LEFT(i)] != EATING &&

state[RIGHT(i)] != EATING )

{

state[i] = EATING;

V(s[i]);

}

}

void get_forks(int i)

{

P(mutex);

state[i] = HUNGRY;

test(i); /*试图得到两支筷子*/

V(mutex);

P(s[i]); /*得不到筷子则阻塞*/

}

void put_forks(int i)

{

P(mutex);

state[i]= THINKING;

test(LEFT(i)); /*看左邻是否进餐*/

test(RIGHT(i)); /*看右邻是否进餐*/

V(mutex);

}

}

哲学家进程如下:

void philosopher(int process)

{

while(true)

{

think();

get_forks(process);

eat();

put_forks(process);

}

}

2.理发师问题:一个理发店有一个入口和一个出口。理发店内有一个可站5 位顾客的站席

区、4 个单人沙发、3 个理发师及其专用理发工具、一个收银台。新来的顾客坐在沙发上等

待;没有空沙发时,可在站席区等待;站席区满时,只能在入口外等待。理发师可从事理

发、收银和休息三种活动。理发店的活动满足下列条件:

1)休息的理发师是坐地自己专用的理发椅上,不会占用顾客的沙发;

2)处理休息状态的理发师可为在沙发上等待时间最长的顾客理发;

3)理发时间长短由理发师决定;

4)在站席区等待时间最长的顾客可坐到空闲的理发上;

5)任何时刻最多只能有一个理发师在收银。

试用信号量机制或管程机制实现理发师进程和顾客进程。

原理:

(1)customer 进程:

首先检查站席区是否已满(stand_capacity),若满选择离开,否则进入站席区,即进入

理发店。在站席区等待沙发的空位(信号量sofa),如果沙发已满,则进入阻塞等待队列,

直到出现空位,在站席区中等待时间最长的顾客离开站席区(stand_capacity)。坐到沙

发上,等待理发椅(barber_chair),如果理发椅已满,则进入阻塞等待队列,直到出现

空位,在沙发上等待时间最长的顾客离开沙发(释放信号量sofa)。坐到理发椅上,释放

准备好的信号(customer_ready),获得该理发师的编号(0~1 的数字)。等待理发师理

发结束(finished[barber_number])。在离开理发椅之前付款(payment),等待收据

(receipt),离开理发椅(leave_barberchair)。最后离开理发店。

这里需要注意几点:

a) 首先是几个需要进行互斥处理的地方,主要包括:进入站席区、进入沙发、进入理发椅

和付款几个地方。

b) 通过barber_chair 保证一个理发椅上最多只有一名顾客。但这也不够,因为单凭

baber_chair 无法保证一名顾客离开理发椅之前,另一位顾客不会坐到该理发椅上,

因此增加信号量leave_barberchair,让顾客离开理发椅后,释放该信号,而理发

师接收到该信号后才释放barber_chair 等待下一位顾客。

c) 在理发的过程中,需要保证是自己理发完毕,才能够进行下面的付款、离开理发椅的活

动。这个机制是通过customer 进程获得给他理发的理发师编号来实现的,这样,当

该编号的理发师释放对应的finished[i]信号的时候,该顾客才理发完毕。

d) 理发师是通过mutex 信号量保证他们每个人同时只进行一项操作(理发或者收款)。

e) 为了保证该顾客理发完毕后马上可以付款离开,就应该保证给该顾客理发的理发师在理

发完毕后马上到收银台进入收款操作而不是给下一位顾客服务。在伪码中由以下机制实

现:即顾客在释放离开理发椅的信号前,发出付款的信号。这样该理发师得不到顾客的

离开理发椅的信号,不能进入下一个循环为下一名顾客服务,而只能进入收款台的收款

操作。直到顾客接到收据后,才释放离开理发椅的信号,离开理发椅,让理发师释放该

理发椅的信号,让下一位等待的顾客坐到理发椅上。

(2)barber 进程

首先将该理发师的编号压入队列,供顾客提取。等待顾客坐到理发椅坐好(信号量

customer_ready),开始理发,理发结束后释放结束信号(finished[i])。等待顾客

离开理发椅(leave_barberchair)(期间去收银台进行收款活动),释放理发椅空闲信

号(barber_chair),等待下一位顾客坐上来。

(3)cash(收银台)进程

等待顾客付款(payment),执行收款操作,收款操作结束,给付收据(receipt)。信号量总表:

信号量wait signal

stand_capacity 顾客等待进入理发店顾客离开站席区

sofa 顾客等待坐到沙发顾客离开沙发

barber_chair 顾客等待空理发椅理发师释放空理发椅

customer_ready 理发师等待,直到一个顾客坐

到理发椅

顾客坐到理发椅上,给理发师

发出信号

mutex 等待理发师空闲,执行理发或

收款操作

理发师执行理发或收款结束,

进入空闲状态

mutex1 执行入队或出队等待入队或出队结束,释放信号

finished[i] 顾客等待对应编号理发师理

发结束

理发师理发结束,释放信号

leave_barberchair 理发师等待顾客离开理发椅顾客付款完毕得到收据,离开

理发椅释放信号

payment 收银员等待顾客付款顾客付款,发出信号

receipt 顾客等待收银员收、开具收据收银员收款结束、开具收据,

释放信号

伪码:

semaphore stand_capacity=5;

semaphore sofa=4;

semaphore barber_chair=3;

semaphore customer_ready=0;

semaphore mutex=3;

semaphore mutex1=1;

semaphore finished[3]={0,0,0};

semaphore leave_barberchair=0;

semaphore payment=0;

semaphore receipt=0;

void customer()

{

int barber_number;

wait(stand_capacity); //等待进入理发店

enter_room(); //进入理发店

wait(sofa); //等待沙发

leave_stand_section(); //离开站席区

signal(stand_capacity);

sit_on_sofa(); //坐在沙发上

wait(barber_chair); //等待理发椅

get_up_sofa(); //离开沙发

signal(sofa);

wait(mutex1);

sit_on_barberchair(); //坐到理发椅上

signal(customer_ready);

barber_number=dequeue(); //得到理发师编号signal(mutex1);

wait(finished[barber_number]); //等待理发结束

pay(); //付款

signal(payment); //付款

wait(receipt); //等待收据

get_up_barberchair(); //离开理发椅

signal(leave_barberchair); //发出离开理发椅信号exit_shop(); //了离开理发店

}

void barber(int i)

{

while(true)

{

wait(mutex1);

enqueue(i); //将该理发师的编号加入队列

signal(mutex1);

wait(customer_ready); //等待顾客准备好

wait(mutex);

cut_hair(); //理发

signal(mutex);

signal(finished[i]); //理发结束

wait(leave_barberchair); //等待顾客离开理发椅信号signal(barber_chair); //释放barber_chair 信号

}

}

void cash() //收银

{

while(true)

{

wait(payment); //等待顾客付款

wait(mutex); //原子操作

get_pay(); //接受付款

give_receipt(); //给顾客收据

signal(mutex);

signal(receipt); //收银完毕,释放信号

}

}

分析:

在分析该问题过程中,出现若干问题,是参阅相关资料后才认识到这些问题的隐蔽性和严重

性的,主要包括:

(1)在顾客进程,如果是在释放leave_barberchair 信号之后进行付款动作的话,很

容易造成没有收银员为其收款的情形,原因是:为该顾客理发的理发师收到leave_barberchair 信号后,释放barber_chair 信号,另外一名顾客坐到理发椅上,

该理发师有可能为这另外一名顾客理发,而没有为刚理完发的顾客收款。为解决这个问题,

就是采取在释放leave_barberchair 信号之前,完成付款操作。这样该理发师无法进入

下一轮循环为另外顾客服务,只能到收银台收款。

(2)本算法是通过给理发师编号的方式,当顾客坐到某理发椅上也同时获得理发师的编号,

如此,当该理发师理发结束,释放信号,顾客只有接收到为其理发的理发师的理发结束信号

才会进行付款等操作。这样实现,是为避免这样的错误,即:如果仅用一个finished 信

号量的话,很容易出现别的理发师理发完毕释放了finished 信号,把正在理发的这位顾

客赶去付款,而已经理完发的顾客却被阻塞在理发椅上的情形。当然也可以为顾客进行编

号,让理发师获取他理发的顾客的编号,但这样就会限制顾客的数量,因为finished[]

数组不能是无限的。而为理发师编号,则只需要三个元素即可。

哲学家就餐问题

实验一 一、实验名称:哲学家就餐问题的实现 二、实验学时:2 三、实验内容和目的: 实验目的:实现哲学家就餐问题,要求不能出现死锁。通过本实验熟悉Linux系统的基本环境,了解Linux下进程和线程的实现。 实验内容:在Unix系统下实现教材2.4.2节中所描述的哲学家就餐问题。要求显示出每个哲学家的工作状态,如吃饭,思考。连续运行30次以上都未出现死锁现象。 四、实验原理: 由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers Problem)是典型的同步问题。该问题是描述有五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五只筷子,他们的生活方式是交替地进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。进餐完毕,放下筷子继续思考。 五、实验器材(设备、元器件) (1)学生每人一台PC,安装WindowsXP/2000操作系统。 (2)局域网络环境。 (3)个人PC安装VMware虚拟机和Ubuntu系统。 六、实验内容:

(一)熟悉Ubuntu系统下的多线程编程。 (二)实现哲学家就餐问题 1. 算法思想 规定奇数号哲学家先拿他左边的筷子,然后再去拿右边的筷子,而偶数号哲学家则相反。按此规定,将是1、2号哲学家竞争1号筷子;3、4号哲学家竞争3号筷子。即五位哲学家都生竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总会有一位哲学家能获得两只筷子而进餐。 2. 流程图

3. 程序代码(重要代码请注释) #include #include #include #include #include #define NOC 5 //number of chopstic #define NOP 5 //number of philosopher sem_t chopstic[NOC]; //semaphore int flag[5]; //philosopher's status void *eat(int i){ int position; int temp = 0; int j = (i+1)%NOC; position = i%2; while(1){ if(position == 0){ //odd take left first sem_wait(&chopstic[i]); printf("philosopher%d get %d\n", i, i); sem_wait(&chopstic[j]); printf("philosopher%d get %d\n", i, j); flag[i] = 1; //philosopher is eating printf("waitting:"); //print others' status while(temp < 5){ if(!flag[temp]) printf("philosopher%d\t", temp); temp++; } temp = 0; printf("\n"); printf("eating:");// print others' status

哲学家就餐问题代码

#include #include #include #include #include #include #include #include #include #define NUM_THREADS_P 5 /*define the number of philosopher*/ #define CHAIR_NUM 4 #define CHOP_NUM 5 int chairflg[CHAIR_NUM][2],dining_num=0; sem_t chair,chopsticks[CHOP_NUM],mutex,mutex1,print_mutex;// 设定信号量pthread_t threads_p[NUM_THREADS_P]; /*philosopher*/ void* philosopher_thread(int tid); int main(){ int i; sem_init(&chair,0,CHAIR_NUM); /*set the value of semaphores*/ for(i=0;i

哲学家就餐问题报告

操作系统 实验报告 实验名称:哲学家就餐问题 班级:信卓1201班 姓名:钟远维 学号:U201213500 日期:2014年10月30日

一、实验目的 1、熟练使用VC6.0编译环境,调试并正确运行程序。 2、理解哲学家就餐问题中出现的问题,进而掌握死锁的必要条件。 3、理解源程序中产生和防止死锁的算法,及相关窗口操作。 4、熟悉哲学家就餐问题流程并写出其伪代码 二、实验内容 有五个哲学家围坐在一圆桌旁(如图1),桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子。每个哲学家的行为是思考,感到饥饿,然后吃通心粉。为了吃通心粉,每个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边去取筷子。 图1 图2 三、实验要求 1、程序需有防止死锁发生采取的措施; 2、程序要有产生死锁的分配方式;

四、实验算法实现 1、不发生死锁的方式 由源码gChopstickState[iLeftChopstick] = iPhilosopher; gChopstickState[iRightChopstick] = iPhilosopher; 知基本思路是要么一下子占用两支筷子要么不占用,先确定两只筷子均没被占用才获取筷子,这样就打破了死锁的必要条件。 伪代码如下; var mutexleftchopstick,mutexrightchopstick; beging: resting; waiting; p(mutexleftchopstick); //先改变左手筷子信号量 p(mutexrightchopstick); //马上改变右手筷子信号量 GetResource(leftchopstick,rightchopstick); //同时占用左右手筷子 eating; v(mutexleftchopstick); //释放资源 v(mutexrightchopstick); end 2、发生死锁的方式 基本思路是有筷子即占用,看似效率很高,但因为资源有限,且不可抢占,很容易发生死锁。 源码理解: gDinerState[iPhilosopher] = WAITING; //wants chopsticks result = WaitForSingleObject(gchopStick[iLeftChopstick], INFINITE); gChopstickState[iLeftChopstick] = iPhilosopher; //得到左手筷子 Sleep(P_DELAY/4); //休眠状态 gDinerState[iPhilosopher] = WAITING; //继续等待另一只手筷子 result = WaitForSingleObject(gchopStick[iRightChopstick], INFINITE); gChopstickState[iRightChopstick] = iPhilosopher; //直到等到右手筷子 伪码书写: var mutexleftchopstick,mutexrightchopstick; beging:

操作系统哲学家问题

操作系统哲学家问题实验报告

实验报告三 实验名称:一、调试验证“有限缓冲”经典同步问题 二、利用Java同步解决“哲学家进餐”问题 日期:2015-11-5 班级:13级计科学号: 姓名: 一、实验目的 1.了解信号量的使用 2.掌握正确使用同步机制的方法 3.实现生产者消费者进程的互斥与同步 4.实现java同步解决“哲学家进餐”问题 二、实验内容 1.调试验证“有限缓冲”经典同步问题 2.利用Java同步解决“哲学家进餐”问题 三、项目要求与分析 1.“有限缓冲”经典同步问题 (1)问题描述 有一群生产者进程在生产产品,此产品提供给消费者去消费。为使生产者和消 费者进程能并发执行,在它们之间设置一 个具有n个缓冲池,生产者进程可将它所 生产的产品放入一个缓冲池中,消费者进 程可从一个缓冲区取得一个产品消费。 (2)问题分析 设两个同步信号量:一个说明空缓冲区的数目,用empty表示,初值为有界缓

冲区的大小N,另一个说明已用缓冲区的 数目,用full表示,初值为0。由于在 执行生产活动和消费活动中要对有界缓 冲区进行操作。有界缓冲区是一个临界资 源,必须互斥使用,所以另外还需要设置 一个互斥信号量mutex,其初值为1。2.“哲学家进餐”问题 (1)问题描述 假如所有的哲学家都同时拿起左侧筷子,看到右侧筷子不可用,又都放下左 侧筷子,等一会儿,又同时拿起左侧筷子,如此这般,永远重复。对于这种情况,即 所有的程序都在无限制地运行,但是都无 法得到任何进展,即出现饿死,所有的哲 学家都吃不上饭。 规定在拿起左侧的筷子后,先检查右面的筷子是否可用。如果不可用,则放下左 侧的筷子,等一段时间后再重复整个过 程。 (2)问题分析 当出现以下情形,在某一瞬间,所有的哲学家都同时启用这个算法,拿起左侧

用多线程同步方法解决哲学家就餐问题报告

课程设计报告书 课程名称:计算机操作系统 题目:用多线程同步方法解决哲学家就餐问题系名: 专业班级: 姓名: 学号: 指导教师: 2016 年 6 月 24 日

武汉华夏理工学院信息工程系 课程设计任务书 课程名称:操作系统原理课程设计指导教师: 班级名称:开课系、教研室:自动化与计算机 一、课程设计目的与任务 操作系统课程设计是《操作系统原理》课程的后续实践课程,旨在通过一周的实践训练,加深学生对理论课程中操作系统概念,原理和方法的理解,加强学生综合运用操作系统原理、Linux系统、C语言程序设计技术进行实际问题处理的能力,进一步提高学生进行分析问题 和解决问题的能力,包含系统分析、系统设计、系统实现和系统测试的能力。 学生将在指导老师的指导下,完成从需求分析,系统设计,编码到测试的全过程。 二、课程设计的内容与基本要求 1、课程设计题目 用多线程同步方法解决哲学家就餐问题 2、课程设计内容 本课程设计要求在Linux操作系统,GCC编译环境下开发。 用c/c++语言在Linux操作系统环境下,通过研究Linux的线程机制和信号量实现哲学家就餐问题的并发控制。为避免死锁,可采用只许4个哲学家入席且桌上有5支筷子的办法。几把椅子可用连续存储单元。 1 每个哲学家取得一双筷子开始用餐后,即时显示“Dining…”和该哲学家的标识符以 及餐桌上有几位哲学家及其所坐的位置。 2 设定共有10个哲学家需用餐。每位用餐耗时10秒钟以上。 3 多个哲学家须共享操作函数代码。 提示: 1 有界缓冲区/连续存储区可用数组实现。 2 编译命令可用: gcc -lpthread -o 目标文件名源文件名 3 多线程编程方法参见电子文档。 3、设计报告撰写格式要求: 1设计题目与要求 2 设计思想 3系统结构 4 数据结构的说明和模块的算法流程图 5 使用说明书(即用户手册):内容包含如何登录、退出、读、写等操作说明 6 运行结果和结果分析(其中包括实验的检查结果、程序的运行情况) 7 自我评价与总结 8 附录:程序清单,注意加注释(包括关键字、方法、变量等),在每个模块前加注释;

哲学家进餐问题代码

哲学家进餐问题代码(JAVA) (2010-10-12 15:24:12) 转载 标签: 分类:Java it 问题描述: 一个哲学家围坐在一张圆桌周围,每个哲学家面前都有一碟通心面。由于面条很滑,所以 要两把叉子才能夹住。相邻两个碟子之间有一把叉子。 哲学家的生活包括两种活动:即吃饭和思考。当一个哲学家觉得饿时,他就试图分两次去 取他左边和右边的叉子,每次拿一把,但不分次序。如果成功地获得了两把叉子,他就开 始吃饭,吃完以后放下叉子继续思考。 问题是: 为每一个哲学家写一段程序描述其行为。要求不能死锁。 class kuai{ String name; boolean Enable = true; public kuai(String name) { https://www.360docs.net/doc/f615413626.html, = name; } public synchronized void pickup() { this.Enable =false;

} public synchronized void putdown() { this.Enable =true; this.notifyAll(); } } class Philosopher extends Thread { String name; kuai left; kuai right; public Philosopher(String name, kuai l, kuai r) { https://www.360docs.net/doc/f615413626.html, = name; left = l; right = r; } public void run() { if(left.Enable) { left.pickup(); } else { while(!left.Enable) {

哲学家就餐问题实验报告

南昌大学实验报告 学生姓名:倪焕学号:8000114018 专业班级:软件工程141班 实验类型:■验证□综合□设计□创新实验日期:2016.5.24 实验成绩: 一、实验项目名称 哲学家就餐问题 二、实验目的 利用PV操作解决哲学家就餐问题 三、软硬件环境 软件:Visual Studio2010 硬件:PC机一台 四、实验内容结果 //哲学家就餐问题的解法 #include #include #include #include #include using namespace std; //命名空间std内定义的所有标识符都有效 const unsigned int PHILOSOPHER_NUM=5; //哲学家数目 const char THINKING=1; /*标记当前哲学家的状态,1表示等待,2表示得到饥饿,3表示正在吃饭*/ const char HUNGRY=2; const char DINING=3; HANDLE hPhilosopher[5]; //定义数组存放哲学家 /*HANDLE(句柄)是windows操作系统中的一个概念。指的是一个核心对象在某一个进程中的唯一索引*/ HANDLE semaphore[PHILOSOPHER_NUM]; // semaphore 用来表示筷子是否可用 HANDLE mutex; // Mutex用来控制安全输出 DWORD WINAPI philosopherProc( LPVOID lpParameter) //返回DWORD(32位数据)的API 函数philosopherProc { int myid; //哲学家id char idStr[128];

操作系统哲学家进餐问题

操作系统实习 报告 一、设计目的: 死锁是进程并发执行过程中可能出现的现象,所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局。哲学家就餐问题是描述死锁的经典例子。为了防止死锁,可以采用资源预分配法或者资源按序分配法。资源预分配法是指进程在运行前一次性地向系统申请它所需要的全部资源,如果系统当前不能够满足进程的全部资源请求,则不分配资源, 此进程暂不投入运行,如果系统当前能够满足进程的全部资源请求, 则一次性地将所申请的资源全部分配给申请进程。 二、设计内容 哲学家进餐问题的模拟。 三、开发环境 windows环境,Myeclipse平台。 四、分析设计 <一>实验原理 哲学家进餐问题描述的是五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五只碗和五只筷子。他们的生活方式是交替地进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右的最靠近他的筷子,只有在他拿到两只筷子时才能进餐。进餐完毕放下筷子继续思考。 由于:①只有拿到两只筷子时,哲学家才能吃饭;②如果筷子已经在他人手上,则该哲学家必须等到他人吃完之后才能拿到筷子;③任何一个哲学家在自己

没有拿到两只筷子吃饭之前,决不放下自己手中的筷子。则可能出现五个哲学家都饥饿时都拿着一直筷子。这样就可能五个哲学家都用不上餐。 该问题可用记录型信号量解决,经分析可知,放在桌子上的筷子是临界资源,在一段时间内只允许一位哲学家使用,为了实现对筷子的互斥使用,可以用一个信号量表示一只筷子,由这五个信号量组成信号量数组。当哲学家饥饿时总是先拿其左边的筷子,成功后,再去拿右边的筷子,又成功后方可就餐。进餐完,又先放下他左边的筷子,再放下右边筷子。这个算法可以保证不会有两个相邻的哲学家同时就餐,但有可能引起死锁。 对于死锁问题可采取这样的几种解决方法: (1)至多只允许四个哲学家同时进餐,以保证至少有一个哲学家可以进餐,最终总会释放出他所用过的两只筷子,从而可使更多的哲学家进餐; (2)仅当左右两只筷子均可用时,才允许哲学家拿起筷子就餐 (3)规定奇数号哲学家先拿起右边筷子,然后再去拿左边筷子,而偶数号哲学家则相反。 (4)把筷子顺序编号0, 1, 2, 3, 4,给每个哲学家分配筷子时,必须依从小号到大号(或者相反顺序)进行。 在本次实习里采用第二种方法解决该问题。 <二>数据及程序结构 总共创建有四个类:哲学家进餐问题类,Philosopher类,ChopstickArray 类,Chopstick类。 Chopstick类来表示筷子,其中包括的布尔型成员变量available来表示该筷子是否可用,成员方法setnum()获取其编号;boolean型成员方法isAvailable()返回其当前available的值。setAvailable(boolean available)这一成员方法是对筷子的available的值进行设置,即设置筷子是否可用。 ChopstickArray类用其中的数组chopsticks[i]来存放五只筷子,并通过哲学家的编号及筷子的编号确定该筷子属于当前哲学家的左右哪边的筷子。 Philosopher类,用来描述哲学家,通过实现Runnable接口的方式来创建线程对象,该类中的方法thinking(),eating()来描述哲学家的状态。通过使用关键词synchronized来给共享资源即Philosopher对象上锁,当一个线问程访问Philosopher中的Thinking()时锁定Philosopher对象,这时其他线程就无法访问其另一个方法eating(),即说明哲学家不能同时处于思考和吃饭的状态中。 public synchronized void thinking() { if(state) /* 如果在思考,说明这个哲学家两边的筷子没用 */ { chopstickArray.getnum(num).setAvailable(true); chopstickArray.getLast(num).setAvailable(true); /*这时哲学家两边的筷子只为可用*/

操作系统课程设计-哲学家进餐问题

潍坊学院计算机工程学院 课程设计说明书 课程名称:____操作系统课程设计_________________设计项目:____哲学家就餐问题____________________学生姓名:_____XXXXXX _________________________学号:____ ___________________专业:______计算机科学与技术________________班级:______一班___________________________指导教师:_______ ___________________________

_2016年__3___月 一、任务与具体要求 哲学家有N个,规定全体到齐后开始讨论,在讨论的间隙哲学家进餐,每人进餐时都需使用刀、叉合一把,所有哲学家刀和叉都拿到后才能进餐。哲学家的人数、餐桌上的布置自行设定,实现刀和叉的互斥使用算法的程序实现。 二、设计说明书包括的内容 1.需求分析 2.系统概要设计 3.系统详细设计 4.系统的主要源代码 5.系统测试及调试 6.总结 7.主要参考文献 三、应完成的图纸 四、评语及成绩 指导教师(签字)_____________

________年____月____日目录 一、需求分析 __________________________________________________________ 1 二、系统概要设计 ______________________________________________________ 2 三、系统详细设计 ______________________________________________________ 3 四、系统的主要源代码 __________________________________________________ 4 五、系统测试及调试 ____________________________________________________ 9 六、总结 _____________________________________________________________ 13 七、主要参考文献 _____________________________________________________ 13

实践 哲学家进餐问题

实践15 哲学家进餐问题 1.实践内容说明 (1)在函数中使用图形方式显示哲学家进餐问题,每个哲学家使用一个线程控制,随机进行进餐或者思考,使用互斥量与事件进行同步与互斥控制。 2.程序性质 (1)Windows 与控制台混合应用程序 (2)多线程 3.运行环境设置 (1)建立项目在Visual C++ 6、0 开发环境,单击New 菜单,弹出New 对话框; 在New 对话框中选择Project 标签切换至Project 标签页; 在Project 标签页得项目列表中选择Win32 Application 选项,Location 输入框输入项目所在得路径,或者单击输入框右侧得按钮,在弹出得Choose Directory 对话框中选择项目所在得磁盘分区与所在得目录;在Project 标签页得Project name 输入框中输入项目名称; Project 标签页中得其她选项保持默认选择(单选框Create new workspace 前有黑点, Platforms 选项框中Win32 前打勾),完成设置界面如图10 所示。 图10 设置项目为Windows 应用 完成设置后单击OK,New 对话框关闭,弹出Win32 Console Application –Step 1 of 1 对话框。在Win32 Console Application –Step 1 of 1 对话框中选择An empty project 单选项。Win32 Console Application –Step 1 of 1 对话框如图11 所示。 图11 说明刚建立得项目为空项目 完成Win32 Console Application –Step 1 of 1 对话框后单击Finish 按钮,Win32 Console Application –Step 1 of 1 对话框关闭,弹出New Project Information 对话框。New Project Information 对话框中显示了当前建立项目得一些信息。New Project Information 对话框如图12 所示。 图12 显示新项目信息 单击New Project Information 对话框中得OK 按钮,关闭New Project Information 对话框, 项目建立步骤完成。 (2)建立文件单击File 菜单中得New 菜单项,弹出New 对话框。在New 对话框中单击Files 标签,切换至Files 标签页; 在Files 标签页得文件列表中选择C++ Source File 选项,在File 输入框中输入文件名。New 对话框设置如图13 所示。

实验一 哲学家就餐问题

实验一哲学家就餐问题

一、实验目的 1.熟练使用VC++6.0编译环境,调试并正确运行程序。 2.熟悉哲学家就餐问题流程。 3.理解哲学家就餐问题中出现的问题,进而掌握死锁的必要条件。 4.熟悉源程序中产生和防止死锁的算法,及其相关窗口操作。 二、实验原理 1.问题描述: 有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每 两人之间放一只筷子,每个哲学家的行为时思考,饥饿,然后吃通心粉,每个哲学 家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边取筷子。 2.防止死锁发生的分配方式: 仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子。这样要么一次占有两 只筷子(所有线程需要的资源)进行下一步吃通心粉,然后释放所有的资源;要么 不占用资源,这样就不可能产生死锁了。 3.产生死锁的分配方式: 当筷子(资源)可用时,先分配左边的筷子,等待一会后再分配右边的筷子,由于 这个过程中,左边的筷子一直没有释放,就可能产生死锁了。 4.程序运行说明: 程序运行过程中会弹出一个MessageBox提示操作者操作: 1)第一个对话框用于选择运行模式 a.选择yes表示采用的是运行的防止死锁的方式,这样的话整个程序可以一直运行下去,不会产生死锁。 b.选择no表示运行产生死锁的方式会弹出第二个对话框。 2)第二个对话框用于选择运行时,线程运行的时间 a.选择yes线程时间比较短,很快就可以死锁。 b.选择no线程时间跟选择yes时的时间差不多,产生死锁的时间稍微长一点。 三、实验过程及分析 1.PhilosopherThread(LPVOID pVoid)函数伪代码 1)不死锁方式 Var mutexleftchopstick,mutexrightchopstick; Beging: Resting; Waiting; P{mutexleftchopstick}; P{mutexrightchopstick}; GetResource{leftchopstick,rightchopstick}; Eating; V{mutexleftchopstick};

哲学家就餐问题

/*inux进程的实现:哲学家就餐问题在 linux 上的程序实现 设有5个哲学家,共享一张放油把椅子的桌子,每人分得一吧椅子.但是桌子上总共只有5支筷子,在每个人两边分开各放一支.哲学家只有在肚子饥饿时才试图分两次从两边拾起筷子就餐. 就餐条件是: 1)哲学家想吃饭时,先提出吃饭的要求; 2)提出吃饭要求,并拿到2支筷子后,方可吃饭; 3)如果筷子已被他人获得,则必须等待该人吃完饭之后才能获取该筷子; 4)任一哲学家在自己未拿到2支筷子吃饭之前,决不放下手中的筷子; 5)刚开始就餐时,只允许2个哲学家请求吃饭. 试问: 1)描述一个保证不会出现两个邻座同时要求吃饭的算法; 2)描述一个既没有两邻座同时吃饭,又没有人饿死的算法; 3)在什么情况下,5个哲学家全都吃不上饭? 哲学家进餐问题是典型的同步问题.它是由Dijkstra提出并解决的.该问题是描述有五个哲学家,他们的生活方式是交替地进行思考和进餐.哲学家们共用一张圆桌,分别坐在周围的五张椅子上.在圆桌上有五个碗和五支筷子,平时一个哲学家进行思考,饥饿时便试图取用其左右岁靠近他的筷子,只有在他拿到两支筷子时才能进餐.进餐完毕,放下筷子继续思考. */ #include #include #include #include #include #include //#include "RasUtil.h" using namespace std; const unsigned int PHILOSOPHER_NUM=5; const char THINKING=1; const char HUNGRY=2; const char DINING=3; sem_t semph[PHILOSOPHER_NUM]; // each fork has a semaphore pthread_mutex_t mutex; // Mutex for printing void* philosopherProc(void* param); int main(int argc, char* argv[])

哲学家就餐问题

计算机操作系统哲学家进餐问题的研究 姓名:陆文静 学号: 1310750012 指导老师:杨婷婷 专业班级:软件工程1301班完成时间: 2015年5月4日

哲学家进餐问题研究 摘要: 一、问题的描述 哲学家就餐问题是一种典型的同步问题,它是由Dijkstra提出并解决的。该问题描述如下:有五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五只筷子,他们的生活方式是交替的进行思考和进餐。设五个哲学家分别编号为A,B,C,D,E,桌子上放着五只筷子,筷子分别编号为0,1,2,3,4,桌子中央有一盘饭菜,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。进餐毕,放下筷子继续思考。 二、解决问题的方案 1、算法描述 semaphore chopstick[5]={1,1,1,1,1}; do{ wait(room); wait(chopstick[i]); wait(chopstick[(i+1)%5]); eat(); signal(chopstick[i]); signal(chopstick[(i+1)%5]); signal(room); Think; } while[ture]; 以上描述中,可保证不会有两个相邻的哲学家同时进餐,但却有可能引起死锁。假如五位哲学家同时饥饿而各自拿起左边的筷子时,就会使五个信号量chopstick均为0;当他们试图拿右边的筷子时,豆浆因无筷子可拿而无限期地等待,进入死锁状态。 2、改进算法描述 描述一种没有人饿死算法,考虑了四种实现的方式(A、B、C、D) A.原理:至多只允许四个哲学家同时进餐,以保证至少有一个哲学家能够进餐, 最终总会释放出他所使用过的两支筷子,从而可使更多的哲学家进餐。以下将room 作为信号量,只允许4 个哲学家同时进入餐厅就餐,这样就能保证至少有一个哲学家可以就餐,而申请进入餐厅的哲学家进入room 的等待队列,根据FIFO 的原则,总会进入到餐厅就餐,因此不会出现饿死和死锁的现象。 伪码:semaphore chopstick[5]={1,1,1,1,1}; semaphore room=4; void philosopher(int i) { while(true)

哲学家吃饭问题 实验报告 操作系统

目录 1.设计题目与要求 (2) 设计目的 设计要求 2.总体设计思想与相关知识 (2) 总体设计思想 问题描述 解决方案 3.数据结构、流程图 (2) 数据结构 流程图 4.源代码 (3) 5.运行结果 (6) 6.结果分析 (7) 7.总结及心得体会 (7)

1.设计题目与要求 设计目的 掌握进程同步问题的解决思路及方法,熟练使用Windows操作系统提供的信号量机制解决各种进程同步问题。 设计要求 设有五个哲学家,共用一张放有五把椅子的餐桌,每人坐在一把椅子上,桌子上有五个碗和五只筷子,每人两边各放一只筷子。哲学家们是交替思考和进餐,饥饿时便试图取其左右最靠近他的筷子。条件: (1) 只有拿到两只筷子时,哲学家才能吃饭。 (2) 如果筷子已被别人拿走,则必须等别人吃完之后才能拿到筷子。 (3) 任意一个哲学家在自己未拿到两只筷子吃饭前,不会放下手中拿到的筷子。 2.总体设计思想与相关知识 总体设计思想 哲学家的生活就是思考和吃饭,即思考,饿了就餐,再思考,循环往复。要求是:每一个哲学家只有在拿到位于他左右的筷子后,才能够就餐;哲学家只能先拿左边的筷子,再去拿右边的筷子,而不能同时去抓他两边的筷子,也不能从其他哲学家手中抢夺筷子;哲学家每次就餐后必须放下他手中的两把筷子后恢复思考,不能强抓住餐具不放。 设计一个程序,能够显示当前各哲学家的状态和桌上餐具的使用情况,并能无死锁的推算出下一状态各哲学家的状态和桌上餐具的使用情况。即设计一个能安排哲学家正常生活的程序。 问题描述 可能出现死锁问题,因为当五个哲学家都饥饿时,都拿着一支筷子,这样就可能五个哲学家都用不上餐。 解决方案 最多允许4个哲学家同时坐在桌子周围。 给所有哲学家编号,奇数号的哲学家必须首先拿左边的筷子,偶数号的哲学家则反之。 为了避免死锁,把哲学家分为三种状态,思考,饥饿,进食,仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子,并且一次拿到两只筷子,否则不拿。3.数据结构及流程图

哲学家就餐问题教学内容

哲学家就餐问题

实验一 一、实验名称:哲学家就餐问题的实现 二、实验学时:2 三、实验内容和目的: 实验目的:实现哲学家就餐问题,要求不能出现死锁。通过本实验熟悉Linux 系统的基本环境,了解Linux下进程和线程的实现。 实验内容:在Unix系统下实现教材2.4.2节中所描述的哲学家就餐问题。要求显示出每个哲学家的工作状态,如吃饭,思考。连续运行30次以上都未出现死锁现象。 四、实验原理: 由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers Problem)是典型的同步问题。该问题是描述有五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五只筷子,他们的生活方式是交替地进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。进餐完毕,放下筷子继续思考。五、实验器材(设备、元器件) (1)学生每人一台PC,安装WindowsXP/2000操作系统。

(2) 局域网络环境。 (3) 个人PC 安装VMware 虚拟机和Ubuntu 系统。 六、实验内容: (一) 熟悉Ubuntu 系统下的多线程编程。 (二)实现哲学家就餐问题 1. 算法思想 规定奇数号哲学家先拿他左边的筷子,然后再去拿右边的筷子,而偶数 号哲学家则相反。按此规定,将是1、2号哲学家竞争1号筷子;3、4号哲学家竞争3号筷子。即五位哲学家都生竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总会有一位哲学家能获得两只筷子而进餐。 2. 流程图 是 否

是 3. 程序代码(重要代码请注释) #include #include #include #include #include #define NOC 5 //number of chopstic #define NOP 5//number of philosopher sem_t chopstic[NOC]; //semaphore int flag[5]; //philosopher's status void *eat(int i){ int position; int temp = 0; int j = (i+1)%NOC; position = i%2; while(1){ if(position == 0){ //odd take left first sem_wait(&chopstic[i]);

哲学家进餐问题讲课教案

哲学家进餐问题

一、需求分析 有一个故事是这样的:假设有五位哲学家围坐在一张圆形餐桌旁,做以下 两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间有一大碗意大利面,每两个哲学家之间有一只餐叉。因为用一只餐叉很难吃到意大利面,所以假设哲学家必须用两只餐叉吃东西。他们只能使用自己左右手边的那两只餐叉。 上边的故事里有五个哲学家(不过我们写的程序可以有N个哲学家),这些哲学家们只思考或吃饭,他们思考的时候不需要任何共享资源,但是吃饭的时候就必须使用餐具,而餐桌上的餐具是有限的,故事里,餐具是叉子,吃饭的时候要用两把叉子把面条从碗里捞出来。很显然把叉子换成筷子会更合理,因为一个哲学家需要两根筷子才能吃饭。 现在引入问题:有六个哲学家很穷,只买得起六根筷子。他们坐成一圈,两个人的中间放一根筷子。哲学家吃饭的时候必须同时得到左手边和右手边的 筷子。如果他身边的任何一位正在使用筷子,那他只有等着。如下图: 1 A A 6 5 3

以上就为我们要处理的哲学家就餐问题,接下来将编写程序模拟解决这个问题。 二、系统概要设计 2.1设计一个程序,能够显示当前各哲学家的状态和桌上餐具的使用情况,并能无死锁的推算出一状态各哲学家的状态和桌上餐具的使用情况。即设计一个能安排哲学家正常生活的程序。 为哲学家设计3种状态,即“等待”“进餐”“思考”。每个哲学家重复进行“等待”->“进餐”->“思考”的行动循环。其中:“等待”->“进餐”:只有一个哲学家处于等待进餐状态,且左右手两边的餐具都处于“空闲”状态时,可以发生这种状态改变。此状态改变发生后,哲学家拿起左右手两边的餐具。“进餐”->“思考”:此状态改变发生后,哲学家放下左右手上的餐具。餐具状态由“使用中”转变为“空闲”。“思考”->“等待”:哲学家思考结束后,无条件转入等待状态。由上所述,程序中应设置6个元素的信号量数组用来保持哲学家之间的同步。 2.2系统平台、语言及工具 (1)操作系统:Windows (2)程序设计语言:C++

哲学家就餐问题

(2013-2014学年 第二学期)重庆理工大学研究生课程论文 课程论文题目:基于ucos-ii操作系统解决哲学家就餐问题 (Problem of Philosophers’ Dining) 课程名称嵌入式系统实验与实践 课程类别□学位课□非学位课 任课教师万文略 所在学院电子学院 学科专业仪器仪表工程 姓名王小辉 学号51307260101

基于ucos-ii的哲学家就餐解决方案 摘要:针对经典的哲学家进餐问题,对多任务同步运行进行了研究。介绍了基于ucos-ii的多任务程序设计和任务间的通信机制,列举了可行的实现方法。并给出了最后的运行结果,使得哲学家能够正常进餐,不被饿死。 关键词:互斥同步多任务任务间通信顺序 一、问题陈列 哲学家进餐问题是荷兰学者Dijkstra 提出的经典问题之一,它是一个信号量机制问题的应用,在操作系统文化史上具有非常重要的地位。假设有5个哲学家,他们花费一生中的时光思考和吃饭。这些哲学家共用一个圆桌,每个哲学家都有一把椅子。在桌子中央是一碗通心面,在桌子上放着5只筷子。哲学家感到饥饿时,并试图拿起与他相近的两只筷子(他与邻近左、右之间的筷子)吃饭。要求: ①哲学家一次只能拿一只筷子,且必须拥有两只筷子才能吃饭。 ②如果筷子已被别人拿走,必须等到别人吃完放下才能拿到筷子。 ③每个哲学家在没拿到第二只筷子时,不会放弃手中已拿到的一只筷子。 ④假定哲学家每次吃饭的时间长度为单位1,吃完一次后则放下两只筷子。如果等待l0个单位时间长度之后,哲学家仍没有得到筷子吃饭,则被饿死。 设计一种方法使得任何一个哲学家都不被饿死。 二、问题分析 对问题分析可知,目前问题的瓶颈在于:死锁。 死锁的发生必须满足以下四个必要条件: ①互斥:至少有一个资源每次只能被一个进程使用,即非共享模式。这里指每只筷子只能被一个哲学家持有。 ②占有并等待。一个进程因请求资源而阻塞时,对已获得的资源保持不放。这里指哲学家在没拿到第二只筷子时,不会放弃手中已拿到的一只筷子。

哲学家就餐问题参考

/*方法1:规定奇数号哲学家先拿左边筷子,偶数号哲学家先拿右边筷子*/ semaphore chopstick[i]={1,1,1,1,1}/*定义信号量数组表示5支筷子,初值为1*/ 第i位哲学家的活动描述为: void philosopher (int i) { do { if (i mod 2) /*如果是奇数号哲学家*/ { wait(chopstick[i]); /*先拿左边筷子,再拿右边筷子*/ wait(chopstick[(i+1)mod 5]); } else /*如果是偶数号哲学家*/ { wait(chopstick[(i+1)mod 5]); /*先拿右边筷子,再拿左边筷子*/ wait(chopstick[i]); } eat; signal(chopstick[i]); signal(chopstick[(i+1)mod 5]); think; while(TRUE); } /*方法2:定义新的信号量room,控制同时就餐的哲学家数目不能超过4人。*/ semaphore chopstick[i]={1,1,1,1,1}/*定义信号量数组表示5支筷子,初值为1*/ semaphore room =4; /*控制最多有4人同时就餐,初值为4*/ 第i位哲学家的活动可以描述为: void philosopher(int i) { while(true) do{ think(); wait(room); //请求进入房间进餐 wait(chopstick[i]); //请求左手边的筷子 wait(chopstick[(i+1)%5]); //请求右手边的筷子 eat(); signal(chopstick[(i+1)%5]); //释放右手边的筷子 signal(chopstick[i]); //释放左手边的筷子 signal(room); //退出房间释放信号量room } }

相关文档
最新文档