/**
* every philosopher is in while loop:
* thinking -> take_forks -> eating -> put_down_forks -> thingking
* 死锁:修改N_ROOM为5,开启take_forks(int id)函数中的sleep(5);
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define N 5 // five philosopher
#define T_EAT 5
#define T_THINK 5
#define N_ROOM 4 //同一时间只允许X人用餐
#define left(phi_id) (phi_id+N-1)%N
#define right(phi_id) (phi_id+1)%N
enum { think , hungry , eat }phi_state[N];
sem_t chopstick[N];
sem_t room;
void thinking(int id){
sleep(T_THINK);
printf("philosopher[%d] is thinking....
", id);
}
void eating(int id){
sleep(T_EAT);
printf("philosopher[%d] is eating....
", id);
}
void take_forks(int id){
//获取左右两边的筷子
printf("philosopher[%d] is trying to get left[%d] chopstick.???????
", id, left(id));
sem_wait(&chopstick[left(id)]);
printf("philosopher[%d] takes left[%d] chopstick.------
", id, left(id));
//sleep(5); //增加死锁几率
printf("philosopher[%d] is trying to get right[%d] chopstick.??????
", id, id);
sem_wait(&chopstick[id]);
printf("philosopher[%d] takes right[%d] chopstick.-----
", id, id);
}
void put_down_forks(int id){
printf("philosopher[%d] put_down_forks...vvvvvv
", id);
sem_post(&chopstick[left(id)]);
sem_post(&chopstick[id]);
}
void* philosopher_work(void *arg){
int id = *(int*)arg;
printf("philosopher init [%d]
", id);
while(1){
thinking(id);
sem_wait(&room);
take_forks(id);
sem_post(&room);
eating(id);
put_down_forks(id);
}
}
int main(){
pthread_t phiTid[N];
int i;
int err;
int *id=(int *)malloc(sizeof(int)*N);
//initilize semaphore
for (i = 0; i < N; i++)
{
if(sem_init(&chopstick[i], 0, 1) != 0)
{
printf("init forks error
");
}
}
sem_init(&room, 0, N_ROOM);
for(i=0; i < N; ++i){
id[i] = i;
err = pthread_create(&phiTid[i], NULL, philosopher_work, (void*)(&id[i])); //这种情况生成的thread id是0,1,2,3,4
if (err != 0)
printf("can't create process for reader
");
}
while(1);
// delete the source of semaphore
for (i = 0; i < N; i++)
{
err = sem_destroy(&chopstick[i]);
if (err != 0)
{
printf("can't destory semaphore
");
}
}
exit(0);
return 0;
}