#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 }