哲学家进餐问题代码

合集下载

哲学家就餐问题代码

哲学家就餐问题代码

哲学家就餐问题代码哲学家就餐问题是一个经典的并发编程问题,描述了五位哲学家围坐在圆桌旁,每个哲学家面前有一碗米饭和一只筷子。

哲学家的生活由思考和就餐两个活动组成,思考时不需要筷子,但就餐时需要同时拿起自己左右两边的筷子才能进餐。

问题在于如何设计算法,使得每位哲学家都能够顺利地进行思考和就餐,而不会发生死锁。

以下是一个简单的解决方案,使用Java语言实现:java.import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;class Philosopher implements Runnable {。

private int id;private Lock leftChopstick;private Lock rightChopstick;public Philosopher(int id, Lock leftChopstick, Lock rightChopstick) {。

this.id = id;this.leftChopstick = leftChopstick;this.rightChopstick = rightChopstick;}。

private void think() {。

System.out.println("哲学家 " + id + " 正在思考");try {。

Thread.sleep((long) (Math.random() 1000));} catch (InterruptedException e) {。

e.printStackTrace();}。

}。

private void eat() {。

leftChopstick.lock();rightChopstick.lock();System.out.println("哲学家 " + id + " 正在就餐");try {。

关于哲学家就餐问题的程序代码分析

关于哲学家就餐问题的程序代码分析

关于哲学家就餐问题的程序代码分析:A. Dining.c变量说明:HINSTANCE hInst应用实例句柄HWND hWndMain主窗口句柄HBITMAP hbmpOffscreen位图句柄BOOL bWaitMultiple用于选择等待的方式(要么死锁,要么一直循环运行)BOOL bFastFood;用于选择进程等待的时间extern int gDinerState[]用于表示哲学家的状态(外部接口) extern int gChopstickState[]用于表示筷子的状态extern HANDLEgchopStick[PHILOSOPHERS]筷子的数组函数说明:LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)处理消息函数:根据进程调度的消息的不同处理不同的消息包括:关闭窗口,销毁资源,画窗口,和重画窗口等BOOL CreateOffscreen()获得当前窗口的一个位图句柄void RenderOffscreen(HDC hDestDC)通过位图句柄画演示的界面1.先画桌子,再画筷子,再画盘子,2.再画哲学家:哲学家用圆表示,根据哲学家的状态选择画笔(为resting 状态时为绿色圆圈,为等待或者,就餐时为红色圆圈)3.最后画哲学家的手:判断的依据是若筷子的编号和哲学家的编号一致,那么认为这根筷子属于这个哲学家(筷子资源空闲)那么可以画手表示哲学家获得了这个筷子。

(获得资源)BOOLInitApplication(HINSTANCEhInstance)初始化应用窗口BOOLInitInstance(HINSTANCE hInstance, int nCmdShow)初始化主窗口弹出选择对话框进行模式选择,并启动进程int PASCALWinMain(HINSTANCEhInstance, HINSTANCEhPrevInstance,LPSTR lpCmdLine, intnCmdShow)调用前面的函数并对进线程消息进行处理B.Mutex.c变量说明:extern HWND hWndMain在Dining.c中定义是这个文件的外部接口extern BOOL bWaitMultiple在Dining.c中定义是这个文件的外部接口extern BOOL bFastFood在Dining.c中定义是这个文件的外部接口int gDinerState[PHILOSOPHERS] 哲学家状态数组int gChopstickState[PHILOSOPHERS] 筷子状态数组HANDLEgchopStick[PHILOSOPHERS]筷子状态数组函数说明:1. DWORD WINAPI PhilosopherThread(LPVOID pVoid)哲学家进程:用于分配给哲学家筷子(资源)通过开始运行时候的对话框的选择来控制资源的分配方式:两中分配方式见二、三所述。

哲学家就餐问题

哲学家就餐问题

哲学家就餐问题运行环境:linux 2.6.38-8 generic代码及说明:/** philosopherEating.cpp** Author: 郭浩东,梁仲海*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h>#include <semaphore.h>#include <string.h>//共有5个哲学家#define PEOPLE_NUM 5//思考状态#define THINKING 1//饥饿状态#define HUNGRY 2//吃的状态#define EATING 3//5根筷子sem_t chopsticks[PEOPLE_NUM];//有一把互斥锁pthread_mutex_tmutex;void *philosopher(void *arg){//对于某个哲学家,id号int id = (int) arg;//初始状态设置为THANKINGint state = THINKING;int right = (id + 1) % PEOPLE_NUM;//右边的哲学家idint left = (id + PEOPLE_NUM - 1) % PEOPLE_NUM;//左边的哲学家id charptrState[32];//5个哲学家不断争夺资源while(1){switch(state){case THINKING:usleep(300);//如果是思考状态,则思考300usstate = HUNGRY;//变为饥饿状态strcpy(ptrState,"Thinking before eat");break;case HUNGRY:strcpy(ptrState,"Hungry");if(sem_wait(&chopsticks[left]) == 0){//阻塞状态if(sem_trywait(&chopsticks[right]) == 0){//非阻塞strcpy(ptrState,"I will Eating");state = EATING;}else{state = THINKING;strcpy(ptrState,"I have not chopsticks");sem_post(&chopsticks[left]);//释放请求的得到的left 筷子printf("Philosopher right chopsticks is busy,right=%d,thread id is %d\n",right,id);}}else{printf("Philosopher left chopsticks is busy,left=%d,thread id is %d\n",left,id);//这句话由于上面被阻塞永远不会输出}break;case EATING:printf("Philosopher fetch left and right chopsticks: (%d,%d), threadid is %d\n",left,right,id);sem_post(&chopsticks[left]);//释放左边的筷子sem_post(&chopsticks[right]);//释放右边的筷子printf("Philosopher release left and right chopsticks: (%d,%d), threadid is %d\n",left,right,id);usleep(500);state = THINKING;//吃完后继续转换为思考状态strcpy(ptrState,"Thinking after eat");break;}pthread_mutex_lock(&mutex);printf("Philosopher is %s, thread id is %d\n",ptrState,id);pthread_mutex_unlock(&mutex);usleep(1000);}pthread_exit((void*)0);}int main(){//存储5个哲学家的id号pthread_ttid[PEOPLE_NUM];inti;pthread_mutex_init(&mutex,NULL);//初始化互斥锁for(i = 0 ; i< PEOPLE_NUM ; i ++){sem_init(&chopsticks[i],0,1);//初始化资源型信号量}for(i = 0 ; i< PEOPLE_NUM ; i ++){pthread_create(&tid[i],NULL,philosopher,(void*)i);//创建5个线程代表5个哲学家,开始争夺筷子}for(i = 0 ; i< PEOPLE_NUM ; i ++){pthread_join(tid[i],NULL);//挂起}return 0;}运行结果截图:运行环境:windows10IDE:codeblocks代码及说明://哲学家就餐问题的解法#include <windows.h>#include <process.h>#include <time.h>#include <stdlib.h>#include <stdio.h>#include <iostream>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操作系统中的一个概念。

哲学家进餐问题

哲学家进餐问题

让偶数编号的哲学 家拿左边的筷子, 然后再去拿右边的 筷子;而奇数号哲 学家则相反 信号量fork[0]— fork[4],初值均为1; 整形变量I=0,1, 2,3,4
为 同 进 步 一 之 步 间 讨 的 论 进 哲 程 学 描 家 述 进 如 餐 右 问 : 题 ,
Semphore fork[0…4]=1; main( ) { co-begin pa(); /pa pb pc pd pe分别代表5位哲学家*/ pb(); pc(); pd)(); pe(); co-end } pa( ) { while (true) { P(fork[0]);} P(fork[1]); Eat; V(fork[1]); V(fork[0]); Thinking; } } /*pb() pc() pd() pe()
pa() */
解决方案二
Philosopher[i] Begin if I mod 2==0 then begin P( fork [i]); P(fork[i+1]mod 5); eat V( fork [i]); V(fork[i+1]mod 5); end else begin P(fork[i+1]mod 5); P( fork [i]); eat V(fork[i+1]mod 5); V( fork [i]); end end
筷子。
Program dining-philosophers; Var fork:array[0..4] of semaphore(:=1); room :semaphore (:=4); i: integer; Procedure philosopher (i: integer); begin repeat think; /*哲学家正在思考*/ wait(room);/*第5位哲学家将被阻塞 在room信号队列*/ wait( fork [i]); /*取其左边的筷 子*/ wait(fork[i+1]mod 5); /*取其右边的筷 子*/ eat; signal(fork[i+1]mod 5); signal (fork [i]); signal (room); forever; end; begin par-begin philosopher(0); philosopher(1); philosopher(2); philosopher(3); philosopher(4); par-end end.

哲学家就餐的问题--java实现

哲学家就餐的问题--java实现

哲学家就餐的问题--java实现先来看看运⾏结果吧:代码分为4个⽂件:Chopstick.javapackage Philosopher;/*** 表⽰筷⼦的类* */public class Chopstick{public Chopstick(){}public Chopstick(int id){this.id = id;}public boolean isAvailable(){return available;}public void setAvailable(boolean available){this.available = available;}public int getId(){return id;}public void setId(int id){this.id = id;}@Overridepublic String toString(){return "筷⼦" + id;}/*** 表⽰筷⼦是否可⽤* */private volatile boolean available = true;private int id;} ChopstickArray.javapackage Philosopher;public class ChopstickArray{public ChopstickArray(){}public ChopstickArray(int size){chopsticks = new Chopstick[size];for(int i = 0; i < chopsticks.length; ++i){chopsticks[i] = new Chopstick(i);}}public Chopstick getId(int id){return chopsticks[id];}public Chopstick getLast(int id){if(id == 0){return chopsticks[chopsticks.length - 1];}else{return chopsticks[id - 1];}}private Chopstick[] chopsticks;}DiningPhilosophersFrame.javapackage Philosopher;import java.awt.FlowLayout;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;public class DiningPhilosophersFrame extends JFrame{public DiningPhilosophersFrame(){panel2.setLayout(new GridLayout(2, 2, 3, 3));panel2.add(label2);panel2.add(label3);panel2.add(label4);JScrollPane js1 = new JScrollPane(thinkingTextArea,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);JScrollPane js2 = new JScrollPane(eatingTextArea,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);JScrollPane js3 = new JScrollPane(waitingTextArea,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);panel2.add(js1);panel2.add(js2);panel2.add(js3);panel1.setLayout(new FlowLayout());panel1.add(label1);panel1.add(panel2);panel1.add(button);setContentPane(panel1);button.addActionListener(new ActionListener(){@Overridepublic void actionPerformed(ActionEvent e){ChopstickArray chopstickArray = new ChopstickArray(5); for(int i = 0; i < 5; i++){new Thread(new Philosopher(i, chopstickArray,thinkingTextArea, eatingTextArea, waitingTextArea)) .start();}}});setSize(300, 400);setVisible(true);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }public static void main(String[] args){new DiningPhilosophersFrame();}private final JPanel panel1 = new JPanel();private final JPanel panel2 = new JPanel();private final JTextArea thinkingTextArea = new JTextArea(5, 10);private final JTextArea eatingTextArea = new JTextArea(5, 10);private final JTextArea waitingTextArea = new JTextArea(5, 10);JLabel label1 = new JLabel("哲学家问题");JLabel label2 = new JLabel("思考");JLabel label3 = new JLabel("吃饭");JLabel label4 = new JLabel("等待");JButton button = new JButton("开始运⾏");} Philosopher.javapackage Philosopher;import java.util.Random;import javax.swing.JTextArea;public class Philosopher implements Runnable{public Philosopher(){}public Philosopher(int id, ChopstickArray chopstickArray,JTextArea thinkingTextArea, JTextArea eatingtextArea,JTextArea waitingTextArea){this.id = id;this.chopstickArray = chopstickArray;this.thinkingTextArea = thinkingTextArea;this.eatingTextArea = eatingtextArea;this.waitingTextArea = waitingTextArea;}public synchronized void thinking(){if(state){ // 如果在思考,说明这个哲学家两⾯的筷⼦没⽤chopstickArray.getId(id).setAvailable(true);chopstickArray.getLast(id).setAvailable(true);String text = thinkingTextArea.getText();thinkingTextArea.setText(text + this + "在思考\n");try{Thread.sleep(1000);}catch(Exception e){e.printStackTrace();}}state = false;}public synchronized void eating(){if(!state){ // 在思考if(chopstickArray.getId(id).isAvailable()){ // 如果哲学家右⼿边的筷⼦可⽤ if(chopstickArray.getLast(id).isAvailable()){ // 如果左⼿边的筷⼦也可⽤ // 然后将这个能吃饭的哲学家两侧的筷⼦都设置为不可⽤chopstickArray.getId(id).setAvailable(false);chopstickArray.getLast(id).setAvailable(false);String text = eatingTextArea.getText();eatingTextArea.setText(text + this + "在吃饭\n");try{Thread.sleep(1000);}catch(Exception e){e.printStackTrace();}}else{// 右⼿边的筷⼦可⽤,但是左⼿边的不可⽤String str = waitingTextArea.getText();waitingTextArea.setText(str + this + "在等待"+ chopstickArray.getLast(id) + "\n");try{wait(new Random().nextInt(100));}catch(Exception e){e.printStackTrace();}}}else{// 如果哲学家右⼿边的筷⼦不可⽤则等待String str = waitingTextArea.getText();waitingTextArea.setText(str + this + "在等待"+ chopstickArray.getId(id) + "\n");try{wait(new Random().nextInt(100)); }catch(Exception e){e.printStackTrace();}}}state = true;}@Overridepublic void run(){for(int i = 0; i < 10; ++i){thinking();eating();}}@Overridepublic String toString(){return " 哲学家 " + id;}private int id;private boolean state;ChopstickArray chopstickArray;JTextArea thinkingTextArea;JTextArea eatingTextArea;JTextArea waitingTextArea;}。

哲学家就餐问题代码

哲学家就餐问题代码
if(chairflg[i][0]==0){ /*the chair is empty*/
chairflg[i][0]=1;
chairflg[i][1]=(int)i;/*philosopher(i) toke the chair*/
break;
}
}
dining_num++;
sem_post(&mutex);
rightIndex = (mythreadId + 1) % PHILOSOPHER_NUM;
myState = THINKING;
while(1)
{
switch(myState)
{
case THINKING:
myState = HUNGRY;
strcpy(strState,"HUNGRY");
break;
if( ret )
{
errNum++;
}
for(i=0;i<PHILOSOPHER_NUM;i++)
{
threadId[i] = i;
sem_init(&semph[i],0,1);
ret=pthread_create(&t_phThread[i], NULL, (void *)philosopher, (void*)(&threadId[i]));
#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;

哲学家进餐问题

哲学家进餐问题

哲学家进餐问题5 个不讲卫生的哲学家围绕一张圆桌而坐,桌子上放着5 支筷子,每两个哲学家之间放一支;哲学家的动作包括思考和进餐,进餐时需要同时拿起他左边和右边的两支筷子,思考时则同时将两支筷子放回原处。

解法一:semaphore Fork[4]={0,1,2,3,4};philosopher_i(){Thinking;Being hungry;P(Fork[i mod 5]);P(Fork[(i + 1) mod 5]);Eating;V(Fork[i mod 5]);V(Fork[(i + 1) mod 5]);}这种解法存在问题,会导致死锁,假如5 个哲学家同时饥饿而各自拿左边的筷子时,会导致5 个筷子的信号量均为0,当他们试图拿右边的筷子时,都将因没有筷子而无限等待。

对于这种死锁问题,可以采用以下几种解决方法:1)仅当哲学家的左右筷子均可用时,才允许其进餐。

(即用AND 信号量机制解决)解法如下:Semaphore array[5]={1,1,1,1,1};Philosopher_i() //i=0,1,2,3,4{While(ture){Think;Sswait(chopstick[(i+1)mod5],chopstick[i]);Eat;Ssignal(chopstick[(i+1)mod5],chopstick[i]);}}2)规定奇数号哲学家先拿左边筷子,然后拿右边筷子;而偶数号哲学家相反。

解法如下:semaphore c[5]={1,1,1,1,1}; 初值均为1;philosopher_i() //i=0,1,2,3,4{If(i mod 2 != 0) //判断是否为奇数号哲学家{ //若为奇数号哲学家先拿左边筷子P(c[i]);P(c[i + 1] mod 5);Eating;V(c[i]);V(c[i + 1] mod 5);}else //若为偶数号哲学家先拿右边筷子{P(c[i + 1] mod 5);P(c[i]);Eating;V(c[i + 1] mod 5);V(c[i]);}}关于解决信号量问题的解题思路:主要是看看进程等的信号和要发出的信号是什么,理清思路。

6个哲学家进餐问题预防死锁

6个哲学家进餐问题预防死锁

红河学院课程设计报告操作系统课程名称:6个哲学家进餐设计题目:院系:工学院专业:计算机科学与技术班级:11计科班曹永前设计者:学号:201101030466指导教师:韦相2013 年 5 月26 日1. 问题描述:一个房间内有6个哲学家,他们的生活就是思考和进食。

哲学家思考后,过一定的时间就会饥饿,饥饿之后就想吃饭,吃饭后再思考。

房间里有一张圆桌,桌子周围放有五把椅子,分别属于五位哲学家每两位哲学家之间有一把叉子,哲学家进食时必须同时使用左右两把叉子。

2. 问题分析1、写出哲学家进餐的算法描述。

用六只筷子解决需要用两双筷子来进餐的六个哲学家,由于每个哲学家都需要其周围的两只筷子,所以筷子是公用信号量,这久需要设置一个互斥信号量,来使六个哲学家互斥的进餐.具体做法将六个信号量设置为0-5,用pv 源于来控制信号量,并将六个哲学家分别编号为0-5.经过仔细分析我们会发现,有这样一个问题存在,就是当每个哲学家都申请到他周围的一只筷子时,由于他们每人都只有一只筷子无法进餐,没有进餐他们就无法释放他们已经得得到的筷子,这样是进餐出于一种僵局,无法继续下去,这就是死锁问题.2、死锁问题的分析与具体的解决方法。

死锁问题就是当每个哲学家都拿到且只拿到一只筷子,这样每个哲学家都无法进餐,也无法释放所得到的筷子,所以解决死锁我们就要从这入手,就是怎样去预防使所有哲学家不要同时去申请他们同一方向的筷子.根据这解决死锁的方法有以下几种:a.每一次最多只能有五个哲学家申请进餐.这样其中的一个哲学家就能申请到两只筷子,就能够进餐,再将筷子释放给其他哲学家进餐.b.用AND信号量,就是哲学家需同时申请其左右两边的筷子,两边都有资源的时候,才能让这个哲学家得到资源,这样哲学家只要申请到筷子就能进餐, 再将筷子释放给其他哲学家进餐.c.用管程机制来实现。

d.我们前面已经将每个哲学家都分配了一个编号,我们可以编号为奇数的哲学家首先去申请其左边的筷子,再去申请其右手边的筷子;让编号为偶数的哲学家,先去申请其右边的筷子,再去申请其左边的筷子.我们可以看出编号为奇数的哲学家左边,与编号为偶数的哲学家的右边为同一只筷子,当其中一个哲学家拿到此筷子后,他另一边的筷子也是空闲的,这样就能避免死锁.主程序中我使用的是最后一种避免死锁的方法.3、用C程序实现哲学家进餐。

哲学家就餐问题--C原代码

哲学家就餐问题--C原代码

哲学家就餐问题--C原代码/*题目:一群哲学家围坐在一个圆桌,手上持有密码m,并从1开始编了号取初值m,哲学家从1开始报数, 报到m的哲学家停止吃饭,退出圆桌,求哲学家退出的顺序。

要求:n和初值m由完家输入.手上的密码随机产生.最后要打印出编号对应的密码,输出哲学家离开的相后顺序分析:可用循环链表实现,链表数据类型为结构体,记录编号和相应密码,另外设标志哲学家报数的变量mouth, 它的值和哲学家嘴上报的数相等,则如果mouth和m相等,该哲学家就应该离开离开前取他的密码交给m,同时将他的编号放另一单链表numbsave保存。

注意编号要从numbsave的最后节点插入。

当循环链表指向自身时停止比较,这个哲学家即是最后离开的一个.依次打印出numbsave中的数即为按编号哲学家离开的先后顺序。

*/#include "stdio.h"#include "conio.h"#include "stdlib.h"struct philosopher /*哲学家就餐结构体*/{ int number; /*编号*/int password;int mouth; /*嘴上报的数*/struct philosopher *next;};struct philosopher *phead,*pend,*pp;struct numbsave /*存放离开顺序*/{ int numsave;struct numbsave *next;};struct numbsave *top=NULL,*numbnew,*numbthis;void main(void){ char *p,d;int b=1,k,n,m,mouthm=1;clrscr(); gotoxy(9,8);printf("please input n m:");scanf("%d%d",&n,&m); /*n为哲学家人数,m为初始密码*/phead=(struct philosopher *)malloc(sizeof(struct philosopher));pend=phead;phead->mouth=1;for(b=1;b<=n-1;b++) /*给哲学家分配随机密码*/{pend->number=b;k=random(20); /*k为0<kwhile(k<=0)k=random(20);pend->password=k;pp=(struct philosopher *)malloc(sizeof(struct philosopher));pend->next=pp; pend=pp;}pend->number=b; /*最后一位哲学家*/k=random(20); while(k<=0) k=random(20); pend->password=k; pend->next=phead; /*形成循环链表*/printf("\n\tphilosopher number correspondence password as followed:\n\t");pp=phead;for(b=1;b<=n;b++){printf("%d:%d\t",pp->number,pp->password);pp=pp->next;}while(pend->next!=pend){if(phead->mouth==m) /*如果嘴上报数和m相等,意味着一个人要走了*/{pp=phead;phead->next->mouth=1; mouthm=1; /*下一位哲学家从一开始报,mm用于将顺序报出数的交给嘴巴*/phead=pend->next=phead->next; /*两个指针一定要相邻*/numbnew=(struct numbsave*)malloc(sizeof(struct numbsave));m=pp->password; /*修改m的值为离开哲学家的password*/numbnew->numsave=pp->number;if(top==NULL) {top=numbnew; top->next=NULL;} /*离开的哲学家的编号存入numbsave 的最后节点*/else { numbthis=top;while(numbthis->next!=NULL) numbthis=numbthis->next;numbthis->next=numbnew; numbnew->next=NULL;}free(pp);}else {pend=pend->next;phead=phead->next; /*让phead指向下一个*/mouthm++;phead->mouth=mouthm; /*嘴巴说我该报mouthm*/}} /*打印离桌顺序*/printf("\n\tphilosopher away from cookdesk in the follow queue:\n\t");while(top!=NULL){ printf("%d ",top->numsave);top=top->next;}printf("%d ",pend->number); /*这个千万别忘了,他是运气的一位*/printf("\n\tpress any key to go back......");while(!kbhit()) ;}。

哲学家吃饭问题(JAVA实现)

哲学家吃饭问题(JAVA实现)
哲学家吃饭问题(JAVA实现)
import java.util.*; //包含常用的数据类型类
public class Dring name;
public DishWare(String name)
{
=name;
philospher1.start();
philospher2.start();
philospher3.start();
philospher4.start();
}
}
}
catch(InterruptedException e){}
synchronized(Knife)
{ //线程的同步,使用synchronized关键词
System.out.println(this.getNumber()+" has "+Knife.getNumber()+" and wait for "+Fork.getNumber());
private String name;
private static Random random=new Random();
public Philospher(String name,DishWare Knife,DishWare Fork) //构造函数,变量初始化
{
=name;
Philospher philospher3=new Philospher("philospher3",knife2,fork2);
Philospher philospher4=new Philospher("philospher4",fork2,knife1);

哲学家就餐问题防止死锁的其他办法

哲学家就餐问题防止死锁的其他办法

哲学家就餐问题防止死锁的其他办法哲学家就餐问题防止死锁的其他办法:1.只允许不超过4个哲学家同时用餐。

这样就至少有一个哲学家可以得到两个筷子。

Program diningphilosophers:Varfork:array[0..4] of semaphore(:=1);room:semaphore(:=4);i=integer;procedurephilsospher (i:interger);beginrepeatthink;wait(room);wait(fork[i]);wait(fork[(i+1) mod 5]);eat;signal (fork[(i+1) mod 5]);signal (fork[i]);signal (room)foreverend;beginparbeginphilosopher(0);philosopher(1);philosopher(2);philosopher(3);philosopher(4);parend会产生死锁的:Program diningphilosophers: Varfork:array[0..4] of semaphore(:=1);i=integer; procedurephilsospher (i:interger); beginrepeatthink;wait(fork[i]);wait(fork[(i+1) mod 5]);eat;signal (fork[(i+1) mod 5]);signal (fork[i]);foreverend;beginparbeginphilosopher(0);philosopher(1);philosopher(2);philosopher(3);philosopher(4);parendend.2.只有哲学家的左右两子筷子均可用时才允许他拿起筷子。

Pi(i=0,1,…4)RepeatIf odd(i) thenBeginWait(chopstick[i]);Wait(chopstick[i]);ElseBeginWait(chopstick[(i+1) mod 5]);Wait(chopstick[i]);EndEatSignal(chopstick[i]);Signal(chopstick[(i+1) mod 5]);Think;Until false;3.规定奇数号哲学家先拿起左边筷子,然后再去拿右边筷子;而偶数号哲学家则相反。

关于哲学家的进餐问题

关于哲学家的进餐问题

P[3] C[2] P[2]
从分析可以看出: 从分析可以看出:哲学家 P[n]在同时获得左手的筷 在同时获得左手的筷 子C[n]和右手的筷子 和右手的筷子 C[(n+4)mod5]后才能进餐 后才能进餐. 后才能进餐
PV信号量对问题的描述 信号量对问题的描述
(先设定每个哲学家都从左手开始拿筷子) 先设定每个哲学家都从左手开始拿筷子)
左手拿起筷子
右手拿起筷子
双手放下筷子
实现过程: 实现过程 tpye philosopher-dinning=monitor Var counter:integer; nonright[0,1……4],nonlock:condition; Procedure[n] entry putleft begin: if counter>=4 then nonlock.wait; counter=counter+1; 拿起左手边的筷子 nonright[(n+1)mod5].wait; end
让加菲用另外一种方法来再 给你 描述下吧
管程方式
“为了解决 个人同时拿起筷子的死锁问题,加菲特别设置 为了解决5个人同时拿起筷子的死锁问题 为了解决 个人同时拿起筷子的死锁问题, 了一个变量counter来记录进程进入的个数和一个条件变量 了一个变量 来记录进程进入的个数和一个条件变量 nolock来定义不会造成死锁的条件。 来定义不会造成死锁的条件。 来定义不会造成死锁的条件 另外,它还把哲学家进餐问题看成为3个过程即:
begin counter:=0;nonlock=0;nonright[]=1,1,1,1,1 end
其中的nonright的设置是 的设置是 其中的 因为当第n位哲学家拿起 因为当第 位哲学家拿起 左手边的筷子时, 左手边的筷子时,相应地 也使第(n+1)mod 5位哲学 也使第 位哲学 家不拿起 拿起右 家不拿起右手边的筷子了

leetcode 力扣 1340 哲学家进餐 题解 算法题

leetcode 力扣 1340 哲学家进餐  题解 算法题

题目:哲学家进餐5 个沉默寡言的哲学家围坐在圆桌前,每人面前一盘意面。

叉子放在哲学家之间的桌面上。

(5 个哲学家,5 根叉子)所有的哲学家都只会在思考和进餐两种行为间交替。

哲学家只有同时拿到左边和右边的叉子才能吃到面,而同一根叉子在同一时间只能被一个哲学家使用。

每个哲学家吃完面后都需要把叉子放回桌面以供其他哲学家吃面。

只要条件允许,哲学家可以拿起左边或者右边的叉子,但在没有同时拿到左右叉子时不能进食。

假设面的数量没有限制,哲学家也能随便吃,不需要考虑吃不吃得下。

设计一个进餐规则(并行算法)使得每个哲学家都不会挨饿;也就是说,在没有人知道别人什么时候想吃东西或思考的情况下,每个哲学家都可以在吃饭和思考之间一直交替下去。

问题描述和图片来自维基百科哲学家从0到4按顺时针编号。

请实现函数void wantsToEat(philosopher, pickLeftFork, pickRightFork, eat, putLeftFork, putRightFork):•philosopher哲学家的编号。

•pickLeftFork和pickRightFork表示拿起左边或右边的叉子。

•eat表示吃面。

•putLeftFork和putRightFork表示放下左边或右边的叉子。

•由于哲学家不是在吃面就是在想着啥时候吃面,所以思考这个方法没有对应的回调。

给你 5 个线程,每个都代表一个哲学家,请你使用类的同一个对象来模拟这个过程。

在最后一次调用结束之前,可能会为同一个哲学家多次调用该函数。

示例:输入:n = 1输出:[[4,2,1],[4,1,1],[0,1,1],[2,2,1],[2,1,1],[2,0,3],[2,1,2],[2,2,2], [4,0,3],[4,1,2],[0,2,1],[4,2,2],[3,2,1],[3,1,1],[0,0,3],[0,1,2],[0,2,2], [1,2,1],[1,1,1],[3,0,3],[3,1,2],[3,2,2],[1,0,3],[1,1,2],[1,2,2]]解释:n 表示每个哲学家需要进餐的次数。

Java哲学家进餐问题多线程

Java哲学家进餐问题多线程

Java哲学家进餐问题多线程J a v a实验三多线程哲学家进餐问题5个哲学家共⽤⼀张圆桌,分别坐在周围的5张椅⼦上,在圆桌上有5个碗和5只筷⼦(注意是5只筷⼦,不是5双),碗和筷⼦交替排列。

他们的⽣活⽅式是交替地进⾏思考(thinking)和进餐(eating)。

平时,⼀个哲学家进⾏思考,饥饿时便试图取⽤其左右最靠近他的两只筷⼦,规定他必须先取左边的筷⼦,再取右边的筷⼦。

只有在他拿到两只筷⼦时才能进餐。

进餐完毕,放下筷⼦继续进⾏思考。

假如5位哲学家同时饥饿,各⾃拿起左边的筷⼦时,再去拿各⾃右边的筷⼦,因为⽆筷⼦可拿⽽陷⼊⽆期限等待(死锁)。

进餐完毕释放他⽤过的两只筷⼦,从⽽使更多的哲学家能够进餐。

使⽤Java的多线程同步技术,实现上述解决⽅案。

解决⽅法⼀:破坏循环等待条件最多允许4个哲学家同时去拿左边的筷⼦,即死锁四⼤必要条件之⼀——破坏循环等待条件。

synchronized关键字易混淆处:⽤法:synchronized(⼀个对象){同步代码块}这⾥synchronized锁住的不是这"⼀个对象",⽽是⽤这"⼀个对象"来当看门⼈,只允许⼀个线程来进⼊synchronized锁住的同步{代码块},所以这个代码块被称作“同步代码块”,当代码块执⾏完后,会让这“⼀个对象”(看门⼈),吼⼀声让其它线程进来。

原理是:每⼀个java对象都关联了⼀个“ monitor lock”,当⼀个线程获取了 monitor lock 后,其它线程如果运⾏到获取同⼀个 monitor 的时候就会被 block 住。

当这个线程执⾏完同步代码,则会释放 monitor lock。

下⾯代码,经过分析后能满⾜最多允许4个哲学家同时去拿左边的筷⼦的条件:分析如下:1.如果不加num<4,synchronized(left)后,如果另⼀个哲学家进程拿了right的筷⼦,另⼀个哲学家⼜拿了这个哲学家右边的筷⼦...依此类推,产⽣循环等待链,即产⽣死锁。

多线程经典哲学家就餐问题C++113种实现

多线程经典哲学家就餐问题C++113种实现

多线程经典哲学家就餐问题C++113种实现哲学家就餐问题核⼼是 避免死锁1. 同时拿起左右叉⼦class DiningPhilosophers {public:DiningPhilosophers(){}void wantsToEat(int philosopher,function<void()> pickLeftFork,function<void()> pickRightFork,function<void()> eat,function<void()> putLeftFork,function<void()> putRightFork){int r =(philosopher+1)%5;mtx.lock();// 要么左右⼀起拿,要么都不拿lock[philosopher].lock();lock[r].lock();pickLeftFork();pickRightFork();mtx.unlock();eat();putRightFork();putLeftFork();lock[r].unlock();lock[philosopher].unlock();}private:std::mutex lock[5];std::mutex mtx;};2. 改变就餐策略(奇数先拿右,偶数先拿左)class DiningPhilosophers {public:DiningPhilosophers(){}void wantsToEat(int philosopher,function<void()> pickLeftFork, function<void()> pickRightFork, function<void()> eat,function<void()> putLeftFork, function<void()> putRightFork){ int l = philosopher;int r =(philosopher+1)%5;if(philosopher &1){lock[r].lock();lock[l].lock();pickRightFork();pickLeftFork();}else{lock[l].lock();lock[r].lock();pickLeftFork();pickRightFork();}eat();putLeftFork();putRightFork();lock[l].unlock();lock[r].unlock();}private:std::mutex lock[5];};3. 限定就餐⼈数(4个⼈就餐)class Semaphore {public:Semaphore(){}void set_count(int k){count = k;}void signal(){unique_lock<std::mutex>lock(mtx);++count;cv.notify_one();}void wait(){unique_lock<std::mutex>lock(mtx);while(count <=0)cv.wait(lock);--count;}private:int count;std::mutex mtx;std::condition_variable cv;};class DiningPhilosophers {public:DiningPhilosophers(){sem.set_count(4);}void wantsToEat(int philosopher,function<void()> pickLeftFork, function<void()> pickRightFork, function<void()> eat,function<void()> putLeftFork, function<void()> putRightFork){ int l = philosopher;int r =(philosopher+1)%5;sem.wait();lock[l].lock();lock[r].lock();pickLeftFork();pickRightFork();eat();putLeftFork();putRightFork();lock[l].unlock();lock[r].unlock();sem.signal();}private:Semaphore sem;std::mutex lock[5];};。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

哲学家进餐问题代码(JAVA)
(2010-10-12 15:24:12)
转载
标签:
分类:Java
it
问题描述:
一个哲学家围坐在一张圆桌周围,每个哲学家面前都有一碟通心面。

由于面条很滑,所以
要两把叉子才能夹住。

相邻两个碟子之间有一把叉子。

哲学家的生活包括两种活动:即吃饭和思考。

当一个哲学家觉得饿时,他就试图分两次去
取他左边和右边的叉子,每次拿一把,但不分次序。

如果成功地获得了两把叉子,他就开
始吃饭,吃完以后放下叉子继续思考。

问题是:
为每一个哲学家写一段程序描述其行为。

要求不能死锁。

class kuai{
String name;
boolean Enable = true;
public kuai(String name)
{
= 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) {
= name;
left = l;
right = r;
}
public void run()
{
if(left.Enable)
{
left.pickup();
}
else
{
while(!left.Enable)
{
try
{
System.out.println(name + " 在等待 "+);
Thread.sleep(500);
}catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
System.out.println(name + " 眼明手快,以迅雷不及掩耳之势一把抓起"+);
try
{
Thread.sleep(500);
}catch (InterruptedException e)
{
e.printStackTrace();
}
if(right.Enable)
{
right.pickup();
}
else
{
while (!left.Enable)
{
try
{
System.out.println(name + "在等待 "+);
Thread.sleep(500);
}catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
System.out.println(name + " 眼明手快,以迅雷不及掩耳之势一把抓起"+);
System.out.println(name + " 左右开弓,狼吞虎咽起来");
try
{
Thread.sleep(2000);
}catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println(name + " 酒足饭饱,打了个饱嗝,心满意足的放下了"++" 和 " +);
left.putdown();
right.putdown();
}
}
public class Eat1
{
public static void main(String args[])
{
kuai k1 = new kuai("筷子1号");
kuai k2 = new kuai("筷子2号");
kuai k3 = new kuai("筷子3号");
kuai k4 = new kuai("筷子4号");
kuai k5 = new kuai("筷子5号");
Philosopher p1 = new Philosopher("老大", k1, k2); Philosopher p2 = new Philosopher("老二", k2, k3); Philosopher p3 = new Philosopher("老三", k3, k4); Philosopher p4 = new Philosopher("老四", k4, k5); Philosopher p5 = new Philosopher("老幺", k5, k1); p1.start();
p2.start();
p3.start();
p4.start();
p5.start();
}
}。

相关文档
最新文档