/********************
philosophers.cpp
哲学家进餐问题
在多线程中如何避免死锁。
问题描述:有五位哲学家围绕着餐桌坐,每一位哲学家要么思考
要么等待,要么吃饭。为了吃饭,哲学家必须拿起两双筷子(分
别放于左右两端)不幸的是,筷子的数量和哲学家相等,所以每
只筷子必须由两位哲学家共享
下面是一种有问题的解法,因为在某个时刻,五个哲学家同时拿起五根左手边的筷子,
则它们会在同一时候对待右手边的筷子,这样会陷入死锁,但是我测试了,这样的几
率并不高经过几个小时,还没有出现。但是我们可以肯定,理论上是肯定会出现死锁的,
我们不能老是靠运气办事,怎么解决这个问题呢
留给下一步的学习吧
要编译此文件请用多线程版的c++库
********************/
#include <windows.h>
#include <iostream>
#include <process.h>
#include <cstdlib>
#include <ctime>
using namespace std;
unsigned int __stdcall philosopher(void *);
void thinking(int);
void eating(int);
void wait_to_eat(int);
void outline(int ,const char *);
//全局变量
CRITICAL_SECTION crout;//这个变量用来保证输出时不会竞争
CRITICAL_SECTION fork[5];//定义五个临界变量,代表五更筷子
int main(int argc,char *argv[])
{
void * hthread[5];
int i;
unsigned int threadid[5];
int arg[5];
int count = 5;
unsigned long retval;
InitializeCriticalSection(&crout);
//初始化临界变量
for(i=0;i<5;i++)
{
InitializeCriticalSection(fork + i);
}
//创建五个哲学家
for(i = 0; i<5;i++)
{
arg[i] = i;
hthread[i] = (void *)_beginthreadex(NULL,0,philosopher,(void *)(arg + i),0,threadid+i);
if((int)hthread[i] == -1)//如果线程创建失败返回-1
{
cerr << "error while create thread " << i <<endl;
cerr << "error code : "<< GetLastError() <<endl;
}
}
//等待所有线程结束
retval = WaitForMultipleObjects(5,hthread,true,INFINITE);//等待多个线程
if(retval == WAIT_FAILED)
{
cerr<< "wait error,error code: "<<GetLastError()<<endl;
}
for(i = 0; i<5;i++)
{
if(CloseHandle(hthread[i]) == false)//关闭句柄
{
cerr << "error while close thread " <<i<<endl;
cerr << "error code: "<<GetLastError()<<endl;
}
}
return 0;
}
/*******************
哲学家的行为
吃饭,等待,思考
*******************/
unsigned int __stdcall philosopher(void *k)
{
int n = ((int *)k)[0];
outline(n," is in!");
srand(time(NULL));
while(true)
{
thinking(n);
wait_to_eat(n);
eating(n);
}
outline(n," is out!");
return n;
}
/*************
思考
随机一段时间
*************/
void thinking(int k)
{
outline(k," is thinking...");
Sleep((rand()%1000) *5);
}
/*************
吃饭
随机一段时间
*************/
void eating(int k)
{
outline(k," is eating...");
Sleep((rand()%1000) *5);
LeaveCriticalSection(fork + (k+1)%5);//放下右边的筷子
//outline(k," give left");
LeaveCriticalSection(fork + k);//放下左边的筷子
//outline(k," give right");
}
/***************
等待吃饭
需要同时获得他两边的筷子
***************/
void wait_to_eat(int k)
{
outline(k," is waiting...");
EnterCriticalSection(fork + k);//获得左边的筷子
//outline(k," take left");
EnterCriticalSection(fork + (k + 1)%5);//获得右边的筷子
//outline(k," take right");
}
/********************
//没有竞争条件的输出函数
********************/
void outline(int who,const char *str)
{
EnterCriticalSection(&crout);
cout<<"process "<<who<<str<<endl;
LeaveCriticalSection(&crout);
}
/********************
philosophers.cpp
哲学家进餐问题
在多线程中如何避免死锁。
问题描述:有五位哲学家围绕着餐桌坐,每一位哲学家要么思考
要么等待,要么吃饭。为了吃饭,哲学家必须拿起两双筷子(分
别放于左右两端)不幸的是,筷子的数量和哲学家相等,所以每
只筷子必须由两位哲学家共享
下面是一种有问题的解法,因为在某个时刻,五个哲学家同时拿起五根左手边的筷子,
则它们会在同一时候对待右手边的筷子,这样会陷入死锁,但是我测试了,这样的几
率并不高经过几个小时,还没有出现。但是我们可以肯定,理论上是肯定会出现死锁的,
我们不能老是靠运气办事,怎么解决这个问题呢
留给下一步的学习吧
要编译此文件请用多线程版的c++库
WWW.54SH.COM
MADE BY EFISH
下面经过了一些修改,把哲学家的个数作为一个宏定义,并减少哲学家的个数为2,
死锁现象马上出现了,真不走运!
********************/
#include <windows.h>
#include <iostream>
#include <process.h>
#include <cstdlib>
#include <ctime>
#define NUM_OF_PH 2 //哲学家的个数
using namespace std;
unsigned int __stdcall philosopher(void *);
void thinking(int);
void eating(int);
void wait_to_eat(int);
void outline(int ,const char *);
//全局变量
CRITICAL_SECTION crout;//这个变量用来保证输出时不会竞争
CRITICAL_SECTION fork[NUM_OF_PH];//定义五个临界变量,代表五更筷子
int main(int argc,char *argv[])
{
void * hthread[NUM_OF_PH];
int i;
unsigned int threadid[NUM_OF_PH];
int arg[NUM_OF_PH];
int count = NUM_OF_PH;
unsigned long retval;
InitializeCriticalSection(&crout);
//初始化临界变量
for(i=0;i<NUM_OF_PH;i++)
{
InitializeCriticalSection(fork + i);
}
//创建五个哲学家
for(i = 0; i<NUM_OF_PH;i++)
{
arg[i] = i;
hthread[i] = (void *)_beginthreadex(NULL,0,philosopher,(void *)(arg + i),0,threadid+i);
if((int)hthread[i] == -1)//如果线程创建失败返回-1
{
cerr << "error while create thread " << i <<endl;
cerr << "error code : "<< GetLastError() <<endl;
}
}
//等待所有线程结束
retval = WaitForMultipleObjects(NUM_OF_PH,hthread,true,INFINITE);//等待多个线程
if(retval == WAIT_FAILED)
{
cerr<< "wait error,error code: "<<GetLastError()<<endl;
}
for(i = 0; i<NUM_OF_PH;i++)
{
if(CloseHandle(hthread[i]) == false)//关闭句柄
{
cerr << "error while close thread " <<i<<endl;
cerr << "error code: "<<GetLastError()<<endl;
}
}
return 0;
}
/*******************
哲学家的行为
吃饭,等待,思考
*******************/
unsigned int __stdcall philosopher(void *k)
{
int n = ((int *)k)[0];
outline(n," is in!");
srand(time(NULL));
while(true)
{
thinking(n);
wait_to_eat(n);
eating(n);
}
outline(n," is out!");
return n;
}
/*************
思考
随机一段时间
*************/
void thinking(int k)
{
outline(k," is thinking...");
Sleep((rand()%1000) *NUM_OF_PH);
}
/*************
吃饭
随机一段时间
*************/
void eating(int k)
{
outline(k," is eating...");
Sleep((rand()%1000) *NUM_OF_PH);
LeaveCriticalSection(fork + (k+1)%NUM_OF_PH);//放下右边的筷子
outline(k," give left");
LeaveCriticalSection(fork + k);//放下左边的筷子
outline(k," give right");
}
/***************
等待吃饭
需要同时获得他两边的筷子
***************/
void wait_to_eat(int k)
{
outline(k," is waiting...");
EnterCriticalSection(fork + k);//获得左边的筷子
outline(k," take left");
EnterCriticalSection(fork + (k + 1)%NUM_OF_PH);//获得右边的筷子
outline(k," take right");
}
/********************
//没有竞争条件的输出函数
********************/
void outline(int who,const char *str)
{
EnterCriticalSection(&crout);
cout<<"process "<<who<<str<<endl;
LeaveCriticalSection(&crout);
}
/********************
philosophers.cpp
哲学家进餐问题
在多线程中如何避免死锁。
问题描述:有五位哲学家围绕着餐桌坐,每一位哲学家要么思考
要么等待,要么吃饭。为了吃饭,哲学家必须拿起两双筷子(分
别放于左右两端)不幸的是,筷子的数量和哲学家相等,所以每
只筷子必须由两位哲学家共享
下面是一种有问题的解法,因为在某个时刻,五个哲学家同时拿起五根左手边的筷子,
则它们会在同一时候对待右手边的筷子,这样会陷入死锁,但是我测试了,这样的几
率并不高经过几个小时,还没有出现。但是我们可以肯定,理论上是肯定会出现死锁的,
我们不能老是靠运气办事,怎么解决这个问题呢
留给下一步的学习吧
要编译此文件请用多线程版的c++库
WWW.54SH.COM
MADE BY EFISH
下面经过了一些修改,把哲学家的个数作为一个宏定义,并减少哲学家的个数为2
死锁现象马上出现了,真不走运!
进行了一些改变,把临界变量变成了互斥变量,让每一个哲学家同时等待每一个
两更筷子
********************/
#include <windows.h>
#include <iostream>
#include <process.h>
#include <cstdlib>
#include <ctime>
#define NUM_OF_PH 3 //哲学家的个数
using namespace std;
unsigned int __stdcall philosopher(LPVOID);
void thinking(int);
void eating(int);
void wait_to_eat(int);
inline void outline(int ,const char *);
//全局变量
CRITICAL_SECTION crout;//这个变量用来保证输出时不会竞争
//CRITICAL_SECTION fork[NUM_OF_PH];//定义五个临界变量,代表五更筷子
//修改之后,用了互斥变量两
void *mutex[NUM_OF_PH + 1];
int main(int argc,char *argv[])
{
void * hthread[NUM_OF_PH];
int i;
unsigned int threadid[NUM_OF_PH];
int arg[NUM_OF_PH];
int count = NUM_OF_PH;
unsigned long retval;
// InitializeCriticalSection(&crout);
//初始化临界变量
for(i=0;i<NUM_OF_PH;i++)
{
// InitializeCriticalSection(fork + i);
mutex[i] = CreateMutex(NULL,false,NULL);
}
// mutex[NUM_OF_PH] = mutex[NUM_OF_PH -1];
//创建五个哲学家
for(i = 0; i<NUM_OF_PH;i++)
{
arg[i] = i;
hthread[i] = (void *)_beginthreadex(NULL,0,philosopher,(LPVOID)(arg + i),0,threadid+i);
if((int)hthread[i] == -1)//如果线程创建失败返回-1
{
cerr << "error while create thread " << i <<endl;
cerr << "error code : "<< GetLastError() <<endl;
}
}
//等待所有线程结束
retval = WaitForMultipleObjects(NUM_OF_PH,hthread,true,INFINITE);//等待多个线程
if(retval == WAIT_FAILED)
{
cerr<< "wait error,error code: "<<GetLastError()<<endl;
}
for(i = 0; i<NUM_OF_PH;i++)
{
if(CloseHandle(hthread[i]) == false)//关闭句柄
{
cerr << "error while close thread " <<i<<endl;
cerr << "error code: "<<GetLastError()<<endl;
}
}
return 0;
}
/*******************
哲学家的行为
吃饭,等待,思考
*******************/
unsigned int __stdcall philosopher(LPVOID k)
{
int n = *(int *) k;
outline(n," is in!");
srand(time(NULL));
while(true)
{
thinking(n);
wait_to_eat(n);
eating(n);
}
outline(n," is out!");
return n;
}
/*************
思考
随机一段时间
*************/
void thinking(int k)
{
outline(k," is thinking...");
Sleep((rand()%1000) *NUM_OF_PH);
}
/*************
吃饭
随机一段时间
*************/
void eating(int k)
{
outline(k," is eating...");
Sleep((rand()%1000) *NUM_OF_PH);
/*
LeaveCriticalSection(fork + (k+1)%NUM_OF_PH);//放下右边的筷子
outline(k," give left");
LeaveCriticalSection(fork + k);//放下左边的筷子
outline(k," give right");
*/
ReleaseMutex(mutex[k]);
outline(k," give left");
ReleaseMutex(mutex[k+1]);
outline(k," give right");
}
/***************
等待吃饭
需要同时获得他两边的筷子
***************/
void wait_to_eat(int k)
{
outline(k," is waiting...");
/*
EnterCriticalSection(fork + k);//获得左边的筷子
outline(k," take left");
EnterCriticalSection(fork + (k + 1)%NUM_OF_PH);//获得右边的筷子
outline(k," take right");
*/
//同时等待两根筷子
WaitForMultipleObjects(2,mutex + k,true,INFINITE);
outline(k," get two");
}
/********************
//没有竞争条件的输出函数
********************/
void outline(int who,const char *str)
{
EnterCriticalSection(&crout);
cout<<"process "<<who<<str<<endl;
LeaveCriticalSection(&crout);
}