仅当哲学家的左右两只筷子均可用时,才允许他拿起筷子进餐
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<iostream>
#include<unistd.h>
#include<semaphore.h>
#define N 5
#define LEFT i
#define RIGHT (i+1)%N
using namespace std;
class Semaphore{
private:
sem_t sem;
public:
Semaphore(int value=1){
sem_init(&sem,0,value);
}
void P(){
sem_wait(&sem);
}
void V(){
sem_post(&sem);
}
};
Semaphore mutex[N];
pthread_t thread[N];
pthread_mutex_t mutex1;
int id[N];
int add=0;
enum {think,hungry,eat}pid_state[N];
void *check_pid_state(int a){
int i =a;
if(pid_state[i]==hungry&&pid_state[LEFT]!=eat&&pid_state[RIGHT]!=eat){
pid_state[i]=eat;
mutex[i].V();
}
}
void *Do_take_fork(int param){
int i =param;
pthread_mutex_lock(&mutex1);
pid_state[i]=hungry;
check_pid_state(i);
pthread_mutex_unlock(&mutex1);
mutex[i].P();
}
void *Do_put_fork(int param){
int i=param;
pthread_mutex_lock(&mutex1);
pid_state[i]=think;
check_pid_state(LEFT);
check_pid_state(RIGHT);
pthread_mutex_unlock(&mutex1);
}
void *solve(void*param){
int i =*((int*)param);
while(true){
if(add>=30){
cout<<"noodles is over"<<endl;
break;
}
cout<<"philo"<<i<<" is thinking"<<endl;
sleep(2);
Do_take_fork(i);
add++;
cout<<add<<endl;
cout<<"philo"<<i<<" is eatting"<<endl;
sleep(1);
Do_put_fork(i);
}
}
void thread_create(){
int tmp;
for(int i=0; i<N; i++){
tmp=pthread_create(&thread[i],NULL,solve,&id[i]);
if(tmp!=0){
cout<<"thread"<<i<<"error"<<endl;
}
}
}
void thread_wait(){
for(int i=0; i<N; i++){
pthread_join(thread[i],NULL);
}
}
int main(){
pthread_mutex_init(&mutex1,NULL);
for(int i=0; i<N; i++){
id[i]=i;
}
thread_create();
thread_wait();
return 0;
}
g++ -o name name.cpp -pthread