1、实验原理
由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers Problem)是典型的同步问题。该问题是描述有五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五只筷子,他们的生活方式是交替地进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。进餐完毕,放下筷子继续思考。
2.实验内容:
显示出每个哲学家的工作状态,如吃饭,思考。连续运行30次以上都未出现死锁现象。
3.分析解决方案一:
现在引入问题的关键:这些哲学家很穷,只买得起五根筷子。他们坐成一圈,两个人的中间放一根筷子。哲学家吃饭的时候必须同时得到左手边和右手边的筷子。如果他身边的任何一位正在使用筷子,那他只有等着。所以我们就假设最多只有4民哲学家在进餐这样就能保证没有死锁的情况。
代码如下:
1 #include<unistd.h> 2 #define NUM 5 3 int ID[NUM]={0,1,2,3,4}; 4 sem_t sem_chopsticks[NUM]; 5 sem_t sem_eaters; 6 int eaters_num=0;//记录已经吃过饭的次数 7 8 //初始化信号量函数 9 void sem_signal_init(){ 10 int i; 11 for(i=0;i<NUM;i++){ 12 if(sem_init(&sem_chopsticks[i],0,1)==-1){ 13 perror("oops:em_init error!"); 14 exit(1); 15 } 16 } 17 if(sem_init(&sem_eaters,0,NUM-1)==-1){ 18 perror("oops:em_init error!"); 19 exit(1); 20 } 21 22 23 } 24 25 26 27 //执行函数,每个线程相当于一个哲学家 来进行 28 void * philosopher(void *ptid){ 29 int pthread_id=*(int *)ptid%NUM; 30 printf("%d philosopher is thinking... ",(int)pthread_id); 31 sem_wait(&sem_eaters); 32 //申请左筷子 33 sem_wait(&sem_chopsticks[pthread_id]); 34 printf("%d philosopher takes chopstick %d... ",(int)pthread_id,(int)pthread_id); 35 //申请右筷子 36 sem_wait(&sem_chopsticks[(pthread_id+1)%NUM]); 37 printf("%d philosopher takes chopstick %d... ",(int)pthread_id,((int)pthread_id+1)%NUM); 38 printf("%d philosopher is eating, %d philosopher had already dined. ",(int)pthread_id,eaters_num); 39 sem_post(&sem_chopsticks[(pthread_id+1)%NUM]) ; 40 sem_post(&sem_chopsticks[pthread_id]); 41 sem_post(&sem_eaters); 42 eaters_num++;//吃过一次的人加加 43 printf("%d philosopher had dined, by now %d philosopher had already dined. ",(int)pthread_id,eaters_num); 44 45 } 46 47 48 49 50 int main(int argc,char *argv[]){ 51 int i,l,j,k; 52 //循环五个线程多少次 53 for(l=0;l<1;++l){ 54 printf("*******%d times try *******",l+1); 55 pthread_t philosopher_threads[NUM]; 56 sem_signal_init(); 57 //循环创建五个线程并执行 58 for(i=0;i<NUM;i++){ 59 60 printf("%d times ",i); 61 if(pthread_create(&philosopher_threads[i],NULL,philosopher,&ID[i])!=0){ 62 perror("oops:pthread_create error!"); 63 exit(1); 64 65 } 66 67 68 } 69 70 //父线程等待子线程都结束才继续执行 71 for(j=0;j<NUM;j++){ 72 pthread_join(philosopher_threads[j],NULL); 73 } 74 //结束销毁信号量 75 sem_destroy(&sem_eaters); 76 for(k=0;k<NUM;++k){ 77 sem_destroy(&sem_chopsticks[k]); 78 } 79 eaters_num=0; 80 sleep(2); 81 82 83 } 84 85 86 87 return 0; 88 }
运行结果如下:
1 philosopher is thinking... 0 philosopher takes chopstick 0... 3 times 1 philosopher takes chopstick 1... 2 philosopher is thinking... 4 times 1 philosopher takes chopstick 2... 1 philosopher is eating, 0 philosopher had already dined. 3 philosopher is thinking... 4 philosopher is thinking... 1 philosopher had dined, by now 1 philosopher had already dined. 2 philosopher takes chopstick 2... 0 philosopher takes chopstick 1... 0 philosopher is eating, 1 philosopher had already dined. 4 philosopher takes chopstick 4... 3 philosopher takes chopstick 3... 0 philosopher had dined, by now 2 philosopher had already dined. 4 philosopher takes chopstick 0... 4 philosopher is eating, 2 philosopher had already dined. 4 philosopher had dined, by now 3 philosopher had already dined. 3 philosopher takes chopstick 4... 3 philosopher is eating, 3 philosopher had already dined. 3 philosopher had dined, by now 4 philosopher had already dined. 2 philosopher takes chopstick 3... 2 philosopher is eating, 4 philosopher had already dined. 2 philosopher had dined, by now 5 philosopher had already dined. -------------------------------- Process exited after 2.127 seconds with return value 0 请按任意键继续. . .
后续方案将继续更新请关注!!!