解决方案1:
#include <stdio.h>
#include <windows.h>
#include <iostream>
using namespace std;
CRITICAL_SECTION cs;
CRITICAL_SECTION ChopStick[5];
int state[5];
DWORD WINAPI Philosopher(LPVOID pArg)
{
int c=(int)pArg;
while(true)
{
state[c]=0;
Sleep(3000);
if(c%2==1)
{
state[c]=1; // 等右
EnterCriticalSection(&ChopStick[(c+1)%5]);
state[c]=2; // 等左
EnterCriticalSection(&ChopStick[c%5] );
}
else
{
state[c]=2; // 等左
EnterCriticalSection(&ChopStick[c%5] );
state[c]=1; // 等右
EnterCriticalSection(&ChopStick[(c+1)%5]);
}
state[c]=3;
Sleep(2000);
LeaveCriticalSection(&ChopStick[c%5]);
LeaveCriticalSection(&ChopStick[(c+1)%5]);
}
return 0;
}
void printf()
{
cout<<endl;
cout<<endl;
for(int i=0;i<5;i++)
printf("\t哲学家%d",i);
cout<<endl;
for(int i=0;i<5;i++)
{
if(state[i]==0)
printf("\t思考");
else if(state[i]==1)
printf("\t等右");
else if(state[i]==2)
printf("\t等左");
else if(state[i]==3)
printf("\t进餐");
}
}
int main()
{
cout<<"哲学家进餐问题"<<endl<<" 规则:五个哲学家,他们交替地进行思考和进餐。";
cout<<"他们分别坐在位于一个圆形餐桌周围的五把椅子上,餐桌上共有五根筷子,分别摆放在每两个相邻座位的中间。";
cout<<"当哲学家思考时,他不与其他人交谈。当哲学家饥饿时,他将拿起和他相邻的两根筷子进行进餐,";
cout<<"但他很可能仅拿到一根,此时旁边的另一根正在他邻居的手中,那么他必须等待。";
cout<<"只有他同时拿到两根筷子时他才能开始进餐。";
cout<<"完成进餐后,他将两根筷子分别放回原位,然后再次开始思考。本例哲学家每隔3秒进餐一次,每次进餐时间为2秒。";
system("pause");
for(int i=0;i<5;i++)
InitializeCriticalSection(&ChopStick[i]);
HANDLE hThread[5];
for(int i=0;i<5;i++)
hThread[i] = CreateThread(NULL, 0, Philosopher, (LPVOID)i, 0, NULL );
while(true)
{
printf();
Sleep(1000);
}
system("pause");
return 0;
}
解决方案2:
#include <stdio.h>
#include <windows.h>
#include <iostream>
using namespace std;
#define N 5
#define LEFT (i + N - 1) % N
#define RIGHT (i + 1) % N
#define THINKING 0
#define HUNGRY 1
#define EATING 2
int state[N];
HANDLE hMutex = NULL;
HANDLE semArr[N] = {NULL};
void test(int i)
{
if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING)
{
state[i] = EATING;
Sleep(1000);
ReleaseSemaphore(semArr[i], 1, NULL);
}
}
void take_forks(int i)
{
WaitForSingleObject(hMutex, INFINITE);
state[i] = HUNGRY;
Sleep(1000);
test(i);
ReleaseMutex(hMutex);
WaitForSingleObject(semArr[i], INFINITE);
}
void put_forks(int i)
{
WaitForSingleObject(hMutex, INFINITE);
state[i] = THINKING;
Sleep(1000);
test(LEFT);
test(RIGHT);
ReleaseMutex(hMutex);
}
DWORD WINAPI Philosopher(LPVOID pArg)
{
int c=(int)pArg;
while(true)
{
take_forks(c);
put_forks(c);
}
return 0;
}
void printf()
{
cout<<endl;
cout<<endl;
for(int i=0;i<5;i++)
printf("\t哲学家%d",i);
cout<<endl;
for(int i=0;i<5;i++)
{
if(state[i]==THINKING)
printf("\t思考");
else if(state[i]==HUNGRY)
printf("\t等待");
else if(state[i]==EATING)
printf("\t进餐");
}
}
int main()
{
cout<<"哲学家进餐问题"<<endl<<" 规则:五个哲学家,他们交替地进行思考和进餐。";
cout<<"他们分别坐在位于一个圆形餐桌周围的五把椅子上,餐桌上共有五根筷子,分别摆放在每两个相邻座位的中间。";
cout<<"当哲学家思考时,他不与其他人交谈。当哲学家饥饿时,他将拿起和他相邻的两根筷子进行进餐,";
cout<<"但他很可能仅拿到一根,此时旁边的另一根正在他邻居的手中,那么他必须等待。";
cout<<"只有他同时拿到两根筷子时他才能开始进餐。";
cout<<"完成进餐后,他将两根筷子分别放回原位,然后再次开始思考。本例哲学家每隔3秒进餐一次,每次进餐时间为2秒。";
system("pause");
for(int i=0;i<5;i++)
{
semArr[i] = CreateSemaphore(NULL, 0, 1, NULL);
}
HANDLE hThread[5];
for(int i=0;i<5;i++)
{
hThread[i] = CreateThread(NULL, 0, Philosopher, (LPVOID)i, 0, NULL );
}
while(true)
{
printf();
Sleep(1000);
}
system("pause");
return 0;
}
解决方案3:
#include <stdio.h>
#include <windows.h>
#include <iostream>
using namespace std;
#define N 5
#define LEFT (i + N - 1) % N
#define RIGHT (i + 1) % N
#define THINKING 0
#define HUNGRY 1
#define EATING 2
int state[N];
HANDLE hMutex = NULL;
HANDLE semArr[N] = {NULL};
HANDLE sem = NULL;
void test(int i)
{
if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING)
{
state[i] = EATING;
Sleep(1000);
//ReleaseSemaphore(semArr[i], 1, NULL);
}
}
void take_forks(int i)
{
// WaitForSingleObject(hMutex, INFINITE);
state[i] = HUNGRY;
Sleep(1000);
test(i);
//ReleaseMutex(hMutex);
//WaitForSingleObject(semArr[i], INFINITE);
}
void put_forks(int i)
{
//WaitForSingleObject(hMutex, INFINITE);
state[i] = THINKING;
Sleep(1000);
test(LEFT);
test(RIGHT);
//ReleaseMutex(hMutex);
}
DWORD WINAPI Philosopher(LPVOID pArg)
{
int c=(int)pArg;
while(true)
{
WaitForSingleObject(sem, INFINITE);
take_forks(c);
put_forks(c);
}
return 0;
}
void printf()
{
cout<<endl;
cout<<endl;
for(int i=0;i<5;i++)
printf("\t哲学家%d",i);
cout<<endl;
for(int i=0;i<5;i++)
{
if(state[i]==THINKING)
printf("\t思考");
else if(state[i]==HUNGRY)
printf("\t等待");
else if(state[i]==EATING)
printf("\t进餐");
}
}
int main()
{
cout<<"哲学家进餐问题"<<endl<<" 规则:五个哲学家,他们交替地进行思考和进餐。";
cout<<"他们分别坐在位于一个圆形餐桌周围的五把椅子上,餐桌上共有五根筷子,分别摆放在每两个相邻座位的中间。";
cout<<"当哲学家思考时,他不与其他人交谈。当哲学家饥饿时,他将拿起和他相邻的两根筷子进行进餐,";
cout<<"但他很可能仅拿到一根,此时旁边的另一根正在他邻居的手中,那么他必须等待。";
cout<<"只有他同时拿到两根筷子时他才能开始进餐。";
cout<<"完成进餐后,他将两根筷子分别放回原位,然后再次开始思考。本例哲学家每隔3秒进餐一次,每次进餐时间为2秒。";
system("pause");
for(int i=0;i<5;i++)
{
semArr[i] = CreateSemaphore(NULL, 0, 1, NULL);
}
sem = CreateSemaphore(NULL, 0, 4, NULL);
HANDLE hThread[5];
for(int i=0;i<5;i++)
{
hThread[i] = CreateThread(NULL, 0, Philosopher, (LPVOID)i, 0, NULL );
}
while(true)
{
printf();
Sleep(1000);
ReleaseSemaphore(sem, 4, NULL);
}
system("pause");
return 0;
}