#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<semaphore.h>
#define false 0
#define true 1
long thread;
long count;
void * SeqEat(void * rank);
void * NoOrder(void * rank);
void * NoDeadLock(void *rank);
int main(int argc,char * argv[]){
pthread_t * thread_handles;
count=strtol(argv[2]+1,NULL,10);
printf("count is :%lld\n",count);
void* (*op)(void *);//op is a pointer to a function,which could change to different functions according to the input argument
if(strcmp(argv[1],"-semaphore")==0) {op=SeqEat;init_SeqEat();}//if argument is "_semaphore",op points to the function SeqEat() and execute the init function,which initialize some variables
else if(strcmp(argv[1],"-noorder")==0) {op=NoOrder;init_NoOrder();}
else if(strcmp(argv[1],"-nodeadlock")==0) {op=NoDeadLock;init_NoDeadLock();}
else {
puts("Wrong argument");//if the first argument is not identified ,then give an error message and return
return 0;
}
thread_handles = malloc(count*sizeof (pthread_t));
for(thread=0;thread<count;thread++){
pthread_create(&thread_handles[thread],NULL,op,(void *)thread);// the thread uses function where op points to
}
for(thread=0;thread<count;thread++){
pthread_join(thread_handles[thread],NULL);
}
free(thread_handles);
return 0;
}
sem_t *canEat;//canEat point to an array of semaphore ,where canEat[i] means ith person can eat or not,he can not eat until canEat[i] is 1
void init_SeqEat(){
canEat = malloc(count*sizeof (sem_t));
sem_init(&canEat[0],0,1);//the 0th person eat first
for(int i=1;i<count;i++) sem_init(&canEat[i],0,0);//ohters now can't eat
}
void * SeqEat(void *r){
long rank=(long)r;
sem_wait(&canEat[rank]);//wait until this person can eat
printf("%lld is eating\n",rank);//he is eating...
sem_post(&canEat[(rank+1)%count]);//after he ate,he must allow the person hehind him could eat
return NULL;
}
sem_t *chop;//chop point to an array of semaphore ,where chop[i] means ith chopstick can, be used or not,it can not be used until chop[i] is 1
void init_NoOrder(){
chop = malloc(count*sizeof(sem_t));
for(int i=0;i<count;i++) sem_init(&chop[i],0,1);//every chopsticks is unused,so set semaphore to 1
}
void * NoOrder(void * r){
long rank=(long)r;
sem_wait(&chop[rank]);//get the left chop first
printf("%lld get the left chop\n",rank);
sem_wait(&chop[(rank+count-1)%count]);//get the left chop first
printf("%lld get the right chop\n",rank);
printf("%lld is eating\n",rank);//he is eating...
sem_post(&chop[(rank+count-1)%count]);//release the left chop first
printf("%lld release the right chop\n",rank);
sem_post(&chop[rank]);//release the left chop first
printf("%lld release the left chop\n",rank);
}
sem_t *max_person;//max_person is a semaphore pointer ,which is set count-1 first,becase I set a constrain that no more than count-1 people could have chopsticks,which could be justfied that deadlock will never happen when under this constrain
void init_NoDeadLock(){
max_person=malloc(1*sizeof(sem_t));
sem_init(max_person,0,count-1);//set max_person to count-1
chop = malloc (count*sizeof (sem_t));
for(int i=0;i<count;i++) sem_init(&chop[i],0,1);//every chopsticks is unused,so set semaphore to 1
}
void * NoDeadLock(void *r){
long rank=(long)r;
long L=rank;//L means the left chopstick
long R=(rank+count-1)%count;//R means the right chopstick
sem_wait(max_person);//if max_person is count-1 ,then wait
sem_wait(&chop[L]);//try to get left chopstick
sem_wait(&chop[R]);//try to get right chopstick
printf("%d is eating\n",rank);
printf("%d end eating\n",rank);
sem_post(&chop[L]);//release the left chopstick
sem_post(&chop[R]);//release the right chopstick
sem_post(max_person);//add max_persoon
}
哲学家问题 pthread信号量实现
最新推荐文章于 2023-08-08 09:36:00 发布