哲学家进餐问题代码
哲学家就餐问题代码

哲学家就餐问题代码哲学家就餐问题是一个经典的并发编程问题,描述了五位哲学家围坐在圆桌旁,每个哲学家面前有一碗米饭和一只筷子。
哲学家的生活由思考和就餐两个活动组成,思考时不需要筷子,但就餐时需要同时拿起自己左右两边的筷子才能进餐。
问题在于如何设计算法,使得每位哲学家都能够顺利地进行思考和就餐,而不会发生死锁。
以下是一个简单的解决方案,使用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实现先来看看运⾏结果吧:代码分为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;}。
哲学家就餐问题代码

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个哲学家进餐设计题目:院系:工学院专业:计算机科学与技术班级:11计科班曹永前设计者:学号:201101030466指导教师:韦相2013 年 5 月26 日1. 问题描述:一个房间内有6个哲学家,他们的生活就是思考和进食。
哲学家思考后,过一定的时间就会饥饿,饥饿之后就想吃饭,吃饭后再思考。
房间里有一张圆桌,桌子周围放有五把椅子,分别属于五位哲学家每两位哲学家之间有一把叉子,哲学家进食时必须同时使用左右两把叉子。
2. 问题分析1、写出哲学家进餐的算法描述。
用六只筷子解决需要用两双筷子来进餐的六个哲学家,由于每个哲学家都需要其周围的两只筷子,所以筷子是公用信号量,这久需要设置一个互斥信号量,来使六个哲学家互斥的进餐.具体做法将六个信号量设置为0-5,用pv 源于来控制信号量,并将六个哲学家分别编号为0-5.经过仔细分析我们会发现,有这样一个问题存在,就是当每个哲学家都申请到他周围的一只筷子时,由于他们每人都只有一只筷子无法进餐,没有进餐他们就无法释放他们已经得得到的筷子,这样是进餐出于一种僵局,无法继续下去,这就是死锁问题.2、死锁问题的分析与具体的解决方法。
死锁问题就是当每个哲学家都拿到且只拿到一只筷子,这样每个哲学家都无法进餐,也无法释放所得到的筷子,所以解决死锁我们就要从这入手,就是怎样去预防使所有哲学家不要同时去申请他们同一方向的筷子.根据这解决死锁的方法有以下几种:a.每一次最多只能有五个哲学家申请进餐.这样其中的一个哲学家就能申请到两只筷子,就能够进餐,再将筷子释放给其他哲学家进餐.b.用AND信号量,就是哲学家需同时申请其左右两边的筷子,两边都有资源的时候,才能让这个哲学家得到资源,这样哲学家只要申请到筷子就能进餐, 再将筷子释放给其他哲学家进餐.c.用管程机制来实现。
d.我们前面已经将每个哲学家都分配了一个编号,我们可以编号为奇数的哲学家首先去申请其左边的筷子,再去申请其右手边的筷子;让编号为偶数的哲学家,先去申请其右边的筷子,再去申请其左边的筷子.我们可以看出编号为奇数的哲学家左边,与编号为偶数的哲学家的右边为同一只筷子,当其中一个哲学家拿到此筷子后,他另一边的筷子也是空闲的,这样就能避免死锁.主程序中我使用的是最后一种避免死锁的方法.3、用C程序实现哲学家进餐。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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();
}
}。