📄 diningphilosopher.c
字号:
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
#include <stdlib.h>
#define N 5
#define LEFT (i-1)%N
#define RIGHT (i+1)%N
#define THINKING 0
#define HUNGRY 1
#define EATING 2
/*重新定义down 和 up函数 */
#define down(LOCK) mutex_lock(LOCK)
#define up(LOCK) mutex_unlock(LOCK)
#define semaphore mutex_t
semaphore mutex; /*临界区互斥*/
semaphore s[N]; /*每个哲学家一个信号量*/
int state[N]; /*记录每个人状态的数组*/
/*
* 测试,是否相邻的哲学家在吃状态
*/
void statecheck(int i)
{
if ( (state[i] == HUNGRY)&&(state[LEFT] != EATING)&&(state[RIGHT] != EATING) ) { //如果左右两边的哲学家都不再吃状态
state[i] = EATING; //则将自已设置为吃状态
up(&s[i]); //打开互斥锁
}
}
/*
* 如是相邻的哲学家没有吃,则正确的取得筷子.
*/
void take_forks (int i)
{
down(&mutex); //锁上互斥锁
state[i] = HUNGRY; //设置为饿态
statecheck(i); //测试自已是否能正确取得筷子
up(&mutex);
down(&s[i]);
}
/* 正确的放下筷子. 改变自身状态成为思考状态. */
void put_forks (int i)
{
down(&mutex); //关上互斥锁
state[i] = THINKING; //设置思考状态
statecheck(LEFT); //查看是否左边的哲学家能进入吃的状
statecheck(RIGHT); //查看是否左边的哲学家能进入吃的状
up(&mutex); //找开互斥锁
}
/*
*思考与吃状态要持续一段时间.
*/
void think(int i)
{
printf("Philosopher %d is thinking...\n", i);
sleep(rand()%60);
}
void eat(int i)
{
printf("Philosopher %d is eating...\n", i);
sleep(rand()%60);
}
/* 哲学家所要做的事.*/
void philosopher (void *arg)
{
int i=(int)arg;
while (1) { //哲学家永远处于这种状态
think(i); //想
take_forks(i); //拿筷子
eat(i); //拿到筷子后开始吃
put_forks(i); //正确放下筷子
}
}
int main ()
{
pthread_t phil[N];
int i;
struct timeval tp;
struct timezone tz;
gettimeofday(&tp,&tz);
srand(tp.tv_sec);//产生随机种子数
pthread_mutex_init(&mutex,NULL);//初始化互斥锁
for (i=0; i<=N-1; i++) {
pthread_create(&phil[i],NULL,philosopher,i);//创建五个线程,但是这儿的i上会出现一个类型转换的警告,不过不影响程序的执行
}
pthread_join(phil[0],NULL);//最后等待线程0的结束,由于线程零不会结束,所以将会进入永远等待状态
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -