哲学家就餐问题
来源:互联网 发布:js重写confirm样式 编辑:程序博客网 时间:2024/04/29 22:11
哲学家进餐问题:
- 在什么情况下5 个哲学家全部吃不上饭?
假如所有的哲学家都同时拿起左侧筷子,看到右侧筷子不可用,又都放下左侧筷子,
等一会儿,又同时拿起左侧筷子,如此这般,永远重复。对于这种情况,即所有的程序都在
无限期地运行,但是都无法取得任何进展,即出现饥饿,所有哲学家都吃不上饭。 这里给出一种避免死锁的解决方式。
最多只允许四个哲学家同时进餐,以保证至少有一个哲学家能够进餐,最终总会释
放出他所使用过的两支筷子,从而可使更多的哲学家进餐。
以下将room 作为信号量,只允 许4 个哲学家同时进入餐厅就餐,这样就能保证至少有一个哲学家可以就餐,而申请进入
餐厅的哲学家进入room 的等待队列,根据FIFO 的原则,总会进入到餐厅就餐,因此不会 出现饿死和死锁的现象。下面给出详细的 C代码实现。
头文件
#pragma once #include <stdio.h> #include <tchar.h> #include <process.h> #include <stdlib.h> #include <Windows.h> #include <time.h> #include <math.h> #include <GLAUX.H> #include <gl/GL.h> #include <gl/GLU.h> #include <gl/glut.h> #include <SDKDDKVer.h>
主程序代码
#include "stdafx.h" HANDLE chopstick[5],room; LPCRITICAL_SECTION cs; const GLfloat Pi = 3.1415926536f; const GLfloat R = 10.0f; //五个中心的坐标 const GLfloat x[5] = { 200, 105, 141, 259, 295 }; const GLfloat y[5] = { 300, 231, 119, 119, 231 }; //代表5个哲学家的状态,0表示思考,1表示吃饭,2表示等待 int state[5] = { 0, 0, 0, 0, 0 }; void initchopstick(){ for (int i = 0; i < 5; i++){ chopstick[i] = CreateSemaphore(NULL, 1, 1, TEXT("chopstick"+i)); } room = CreateSemaphore(NULL, 4, 4, TEXT("room")); } int srandNum(){ srand(time(0)); return (rand() % 100); } void think(int i){ printf("哲学家%d正在思考\n", i); state[i] = 0; Sleep((DWORD(srandNum() % 10000+2000))); } void eat(int i){ printf("哲学家%d正在吃饭\n", i); state[i] = 1; Sleep((DWORD(srandNum() % 10000+2000))); } void philosopher(PVOID p) { int i = (int)p; while (true) { think(i); //等待状态 state[i] = 2; WaitForSingleObject(room, INFINITE); WaitForSingleObject(chopstick[i], INFINITE);//请求左手边的筷子 WaitForSingleObject(chopstick[(i + 1) % 5], INFINITE);//请求右手边的筷子 EnterCriticalSection(cs); eat(i); LeaveCriticalSection(cs); Sleep(500); ReleaseSemaphore(chopstick[(i + 1) % 5],1,NULL); //释放右手边的筷子 ReleaseSemaphore(chopstick[i],1,NULL); //释放左手边的筷子 ReleaseSemaphore(room,1,NULL); //退出房间释放信号量room } } // 函数RenderScene用于在窗口中绘制需要的图形 void RenderScene(void) { //用当前清除色清除颜色缓冲区,即设定窗口的背景色 glClear(GL_COLOR_BUFFER_BIT); for (int i = 0; i < 5; i++){ //设置当前绘图使用的RGB颜色 if (state[i] == 2){ glColor3f(1.0f, 1.0f, 0.0f);//黄色代表等待 } else if (state[i] == 1){ glColor3f(0.0f, 1.0f, 0.0f);//绿色代表吃饭 } else if (state[i] == 0){ glColor3f(1.0f, 0.0f, 0.0f); } glRectf(x[i] - R, y[i] - R, x[i] + R, y[i] + R); } //清空命令缓冲区并交换帧缓存 glutSwapBuffers(); } // 函数ChangeSize是窗口大小改变时调用的登记函数 void ChangeSize(GLsizei w, GLsizei h) { if (h == 0) h = 1; //设置视区尺寸 glViewport(0, 0, w, h); // 重置坐标系统,使投影变换复位 glMatrixMode(GL_PROJECTION); glLoadIdentity(); // 建立修剪空间的范围 if (w <= h) glOrtho(0.0f, 400.0f, 0.0f, 400.0f*h / w, 1.0f, -1.0f); else glOrtho(0.0f, 400.0f*w / h, 0.0f, 400.0f, 1.0f, -1.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void TimerFunction(int value) { glutPostRedisplay(); glutTimerFunc(33, TimerFunction, 1); } void SetupRC(void) { //设置窗口清除色为蓝色 glClearColor(1.0f, 1.0f, 1.0f, 1.0f); } int _tmain(int argc, _TCHAR* argv[]) { initchopstick(); cs = (LPCRITICAL_SECTION)malloc(sizeof(LPCRITICAL_SECTION)); InitializeCriticalSection(cs); for (int i = 0; i < 5; i++){ _beginthread(philosopher, NULL, (PVOID)i); } glutInitDisplayMode(GLUT_RGB |GLUT_DOUBLE); glutInitWindowSize(800, 800); glutCreateWindow("Draw"); glutDisplayFunc(RenderScene); glutReshapeFunc(ChangeSize); glutTimerFunc(33, TimerFunction, 1); SetupRC(); glutMainLoop(); Sleep(INFINITE); DeleteCriticalSection(cs); return 0; }
0 0
- 哲学家就餐问题
- 哲学家就餐问题
- 哲学家就餐问题
- 哲学家就餐问题 锁
- 哲学家就餐问题
- 哲学家就餐问题
- 关于哲学家就餐问题
- 哲学家就餐问题
- 哲学家就餐问题
- 哲学家就餐问题
- 哲学家就餐问题
- 哲学家就餐问题
- 哲学家就餐问题
- 哲学家就餐问题
- 哲学家就餐问题
- 哲学家就餐问题
- 哲学家就餐问题
- 多线程--哲学家就餐问题
- 测试csdn使用WLW发布日志
- 安装64位oracle,pl/sql连接不了数据库问题
- C++ Primer Plus第六版编程练习11.1解答
- ios&android c++文件操作
- 数据结构:树
- 哲学家就餐问题
- HDU 3065 病毒侵袭持续中 AC自动机
- [150422][C++]数据结构复习——队列实现源码
- jquery和javascript的区别(常用方法比较)
- Intent和PendingIntent的区别
- eclipse的常用设置
- C++ Primer Plus第六版编程练习11.2解答
- JavaOO-①
- hdu2881 dp