该问题的描述是:五个哲学家共用一张圆桌,分别坐在周围的5张椅子上,在圆桌上有5个碗和5只筷子,,他们的生活方式是交替进行思考和进餐,平时,一个哲学家进行思考和饥饿,平时,一个哲学家进行思考,饥饿的时候便试图取用其作用最靠近的筷子,只有在他拿到两至筷子时才能进餐,进餐完毕,放下筷子进行思考
现在呢:我们使用的源代码如下:
// 哲学家.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
///文件描述:哲学家就餐问题,共有5个哲学家,坐成一个环,两个哲学家之间有
/// 一根筷子,每个哲学家有两根筷子才能吃饭,放下筷子就只能思考
/// 我们可以认为建立有5个线程,表示5个哲学家,因为有5跟筷子,所
/// 以,当每个人一根筷子,则会产生死锁,我们设置最多有4个人同时
// 就餐
#include<iostream>
#include<Windows.h>
using namespace std;
#define PHYSICAL 5
HANDLE hMutext[PHYSICAL]={0};
int index=0;
DWORD Dinner(LPVOID param )
{
int* current=(int*)param;
while(1)
{
if(((index>=*current)&&(index-*current)<=3)||(index<*current)&&(*current-index<=3))
{
//可以进行尝试就餐了
::WaitForSingleObject(hMutext[*current],INFINITE);
::WaitForSingleObject(hMutext[(*current+1)%PHYSICAL],INFINITE);
cout<<"哲学家"<<*current<<"正在就餐\n";
index=(index+1)%PHYSICAL;
cout<<"当前索引是:"<<index<<endl;
::Sleep(500);
::ReleaseMutex(hMutext[(*current+1)%PHYSICAL]);//现在这两个的顺序不能换,因为必须先放掉比较大的那一个,然后旁边的哲学家才能
//拿起来进行使用
::ReleaseMutex(hMutext[(*current)%PHYSICAL]);
}
}
return 0;
}
int main()
{
//初始化互斥变量,初始化要传递给线程的数组
Physical=new int[PHYSICAL];
for(int i=0;i<PHYSICAL;i++)
{
hMutext[i]=::CreateMutexA(NULL,false,NULL);
Physical[i]=i;
}
//然后开始进行开辟线程
HANDLE *hThread=NULL;
hThread=new HANDLE[PHYSICAL];
int mm=0;
for(int i=0;i<PHYSICAL;i++)
{
DWORD tmp=0;
hThread[i]=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Dinner,&i,0,&tmp);
}
::WaitForMultipleObjects(PHYSICAL,hThread,true,INFINITE);
for(int i=0;i<PHYSICAL;i++)
{
CloseHandle(hThread[i]);
CloseHandle(hMutext[i]);
}
}
这样的话,我们在看输出的时候,会发现,最后输出的一直是 哲学家5正在就餐,一直就是,可是我们传递过去的是从0~45种不同的数值啊,这时候我们就会发现,线程传递的是地址,而现在我们传递的是局部变量地址i,而i是一直变化的,0~4,最后变成的是5,所以就会出现现在的这种情况了
所以我们需要为线程使用的数据开辟专门的空间局部变量是行不通的,所以修改如下:
// 哲学家.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
///文件描述:哲学家就餐问题,共有5个哲学家,坐成一个环,两个哲学家之间有
/// 一根筷子,每个哲学家有两根筷子才能吃饭,放下筷子就只能思考
/// 我们可以认为建立有5个线程,表示5个哲学家,因为有5跟筷子,所
/// 以,当每个人一根筷子,则会产生死锁,我们设置最多有4个人同时
// 就餐
#include<iostream>
#include<Windows.h>
using namespace std;
#define PHYSICAL 5
HANDLE hMutext[PHYSICAL]={0};
int index=0;
int *Physical;
DWORD Dinner(LPVOID param )
{
int* current=(int*)param;
while(1)
{
if(((index>=*current)&&(index-*current)<=3)||(index<*current)&&(*current-index<=3))
{
//可以进行尝试就餐了
::WaitForSingleObject(hMutext[*current],INFINITE);
::WaitForSingleObject(hMutext[(*current+1)%PHYSICAL],INFINITE);
cout<<"哲学家"<<*current<<"正在就餐\n";
index=(index+1)%PHYSICAL;
cout<<"当前索引是:"<<index<<endl;
::Sleep(500);
::ReleaseMutex(hMutext[(*current+1)%PHYSICAL]);
::ReleaseMutex(hMutext[(*current)%PHYSICAL]);
}
}
return 0;
}
int main()
{
//初始化互斥变量,初始化要传递给线程的数组
Physical=new int[PHYSICAL];
for(int i=0;i<PHYSICAL;i++)
{
hMutext[i]=::CreateMutexA(NULL,false,NULL);
Physical[i]=i;
}
//然后开始进行开辟线程
HANDLE *hThread=NULL;
hThread=new HANDLE[PHYSICAL];
int mm=0;
for(int i=0;i<PHYSICAL;i++)
{
DWORD tmp=0;
hThread[i]=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Dinner,&Physical[i],0,&tmp);
}
::WaitForMultipleObjects(PHYSICAL,hThread,true,INFINITE);
for(int i=0;i<PHYSICAL;i++)
{
CloseHandle(hThread[i]);
CloseHandle(hMutext[i]);
}
}