哲学家进餐问题求解!!!!!!

lsxshui 2012-04-19 06:59:08
1、问题描述
哲学家进餐问题是荷兰学者Dijkstra 提出的经典问题之一,它是一个信号量机制问题的应用,在操作系统文化史上具有非常重要的地位。假设有5个哲学家,他们花费一生中的时光思考和吃饭。这些哲学家共用一个圆桌,每个哲学家都有一把椅子。在桌子中央是一碗通心面,在桌子上放着5只筷子。当一个哲学家思考时,他与其他同事不交互。时而,哲学家会感到饥饿,并试图拿起与他相近的两只筷子(他与邻近左、右之间的筷子)。一只筷子一次只能被一个哲学家拿起。显然,他不能从其他哲学家手里拿走筷子。当一个饥饿的哲学家同时有两只筷子时,他就可以吃饭。当吃完后,他会放下两只筷子,并再次开始思考。
(1)至多只允许四个哲学家同时去拿左边的筷子,最终能保证至少有一个哲学家能够进餐。
(2)规定奇数号哲学家先拿他左边的筷子,然后再去拿右边的筷子;而偶数号哲学家则相反。按此规定,将是1、 2号哲学家竞争1号筷子;3、4号哲学家竞争3号筷子。即五位哲学家都先竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总会有一位哲学家能获得两只筷子而进餐。
2、程序实现
在已提供的哲学家进餐程序中修改代码实现以上(1)和(2)的内容。
代码:
#include <stdio.h>
#include <windows.h>
#include <iostream.h>
#include <winbase.h>

#define MAX_NUM 5

struct tagThread{
DWORD IDThread;
HANDLE hThread;
int iParam;
};
HANDLE hMutex[MAX_NUM+1];
//---------------------------------------------------------------------------
DWORD WINAPI PhilosopherOrder(LPVOID pParam)
{
int iPhiloID=*(int *)pParam;
char strPhiloID[20];
char info[64];

sprintf(strPhiloID, "%d ",iPhiloID );
strcpy(info, "第 ");
strcat(info,strPhiloID);
strcat(info, "个哲学家 ");

do
{
MessageBox(NULL, "正在思考。。。 ", info, MB_OK|MB_ICONINFORMATION);

MessageBox(NULL, "想进餐,企图使用左筷子 ", info, MB_OK|MB_ICONINFORMATION);
WaitForSingleObject(hMutex[iPhiloID],INFINITE);
MessageBox(NULL, "拿到左筷子,企图使用右筷子 ", info, MB_OK|MB_ICONINFORMATION);
WaitForSingleObject(hMutex[iPhiloID+1],INFINITE);


MessageBox(NULL, "拿到两只筷子,正在进餐。。。 ", info, MB_OK|MB_ICONINFORMATION);

MessageBox(NULL, "筷子使用完毕,准备通告 ", info, MB_OK|MB_ICONINFORMATION);
ReleaseMutex(hMutex[iPhiloID]);
ReleaseMutex(hMutex[(iPhiloID+1)%MAX_NUM]);

} while( MessageBox(NULL, "通告完毕,继续思考进餐吗? ", info, MB_YESNO|MB_ICONINFORMATION)
==IDYES);
ExitThread(NO_ERROR);
return 0;
}
//-----------------------------------------

DWORD WaitForMultipleObjects(
DWORD nCount, // number of handles in the object handle array
CONST HANDLE *lpHandles, // pointer to the object-handle array
BOOL bWaitAll, // wait flag
DWORD dwMilliseconds // time-out interval in milliseconds
);

DWORD WINAPI PhilosopherAll(LPVOID pParam)
{
int iPhiloID=*(int *)pParam;
char strPhiloID[20];
char info[64];

sprintf(strPhiloID, "%d ",iPhiloID );
strcpy(info, "第 ");
strcat(info,strPhiloID);
strcat(info, "个哲学家 ");

do
{
MessageBox(NULL, "正在思考。。。 ", info, MB_OK|MB_ICONINFORMATION);

MessageBox(NULL, "想进餐,企图使用筷子 ", info, MB_OK|MB_ICONINFORMATION);
WaitForMultipleObjects(
2, // number of handles in the object handle array
&(hMutex[iPhiloID]), // pointer to the object-handle array
TRUE, // wait flag
INFINITE // time-out interval in milliseconds
);

MessageBox(NULL, "拿到两只筷子,正在进餐。。。 ", info, MB_OK|MB_ICONINFORMATION);

MessageBox(NULL, "筷子使用完毕,准备通告 ", info, MB_OK|MB_ICONINFORMATION);
ReleaseMutex(hMutex[iPhiloID]);
ReleaseMutex(hMutex[iPhiloID+1]);

} while( MessageBox(NULL, "通告完毕,继续思考进餐吗? ",
info, MB_YESNO|MB_ICONINFORMATION)
==IDYES);
ExitThread(NO_ERROR);
return 0;
}
//-----------------------------------------
int main()
{
int i;
for (i=0;i <MAX_NUM;i++)
hMutex[i]=CreateMutex(NULL,false,NULL);
hMutex[MAX_NUM]=hMutex[0];

tagThread arrThread[MAX_NUM];
int Flag;
Flag=MessageBox(NULL, "全部分配方案(Y),有序分配方案(N) ", "选择 ",
MB_YESNO|MB_ICONINFORMATION);

cout<< "CreateThread Start " << endl;
for(i=0;i <MAX_NUM;i++)
{ arrThread[i].iParam=i;
if (Flag==IDYES)
arrThread[i].hThread =CreateThread(NULL,0, PhilosopherAll,
&(arrThread[i].iParam),0,
&(arrThread[i].IDThread));
else
arrThread[i].hThread =CreateThread(NULL,0,PhilosopherOrder,
&(arrThread[i].iParam),0,
&(arrThread[i].IDThread));
if (arrThread[i].hThread == NULL)
cout << "CreateThread error " << endl;
}
cout << "CreateThread End " << endl;

cin.get();
for (i=0;i <MAX_NUM;i++)
CloseHandle(hMutex[i]);
return 0;
}

...全文
1127 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
MarioXia 2012-04-25
  • 打赏
  • 举报
回复

p(mutex);
p(fork[i]);
p(fork[i+1]);
v(mutex);
//就餐
v(fork[i]);
v(fork[i+1]);
lsxshui 2012-04-24
  • 打赏
  • 举报
回复
我要源码啊???
giant1st 2012-04-22
  • 打赏
  • 举报
回复
条件1没什么特别,关键是条件2
你的程序中必须引入一个 状态数组来跟踪每一个哲学家的三种状态【想吃饭,在吃饭,吃完饭】int state[N];
然后修改我下面示例中的test函数即可。

另外: HANDLE hMutex[MAX_NUM+1]; 中引入6个mutex是对的,但是你的第6个没有用到啊,他应该对应于示例程序中的“semaphore mutex = 1; ”


下面的就是《现代操作系统》2.4.1上面的答案:

#define N              5   /* number of philosophers */
#define LEFT (i+N−1)%N /* number of i's left neighbor */
#define RIGHT (i+1)%N /* number of i's right neighbor */
#define THINKING 0 /* philosopher is thinking */
#define HUNGRY 1 /* philosopher is trying to get forks */
#define EATING 2 /* philosopher is eating */
typedef int semaphore; /* semaphores are a special kind of int */
int state[N]; /* array to keep track of everyone's state */
semaphore mutex = 1; /* mutual exclusion for critical regions */
semaphore s[N]; /* one semaphore per philosopher */

void philosopher (int i) /* i: philosopher number, from 0 to N−1 */
{
while (TRUE) { /* repeat forever */
think(); /* philosopher is thinking */
take_forks(i); /* acquire two forks or block */
eat(); /* yum-yum, spaghetti */
put_forks(i); /* put both forks back on table */
}
}

void take_forks(int i) /* i: philosopher number, from 0 to N−1 */
{
down(&mutex); /* enter critical region */
state[i] = HUNGRY; /* record fact that philosopher i is hungry */
test(i); /* try to acquire 2 forks */
up(&mutex); /* exit critical region */
down(&s[i]); /* block if forks were not acquired */
}

void put_forks(i) /* i: philosopher number, from 0 to N−1 */
{
down(&mutex); /* enter critical region */
state[i] = THINKING; /* philosopher has finished eating */
test(LEFT); /* see if left neighbor can now eat */
test(RIGHT); /* see if right neighbor can now eat */
up(&mutex); /* exit critical region */
}

void test(i) /* i: philosopher number, from 0 to N−1 */
{
if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING) {
state[i] = EATING;
up(&s[i]);
}
}


Linkhai 2012-04-19
  • 打赏
  • 举报
回复
初学者,对你的代码表示压力很大
evencoming 2012-04-19
  • 打赏
  • 举报
回复
闲的蛋疼的哲学家。。。
无视他们

64,687

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧