zoukankan      html  css  js  c++  java
  • linux c语言 哲学家进餐---信号量PV方法一

    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
    请按任意键继续. . .

    后续方案将继续更新请关注!!!

  • 相关阅读:
    不开心的事
    git push 时 error: RPC failed; HTTP 400 curl 55 Send failure: Connection was reset 问题
    Java多线程相关
    angularJS 级联下拉框
    leetcode260 Single Number III
    -2147483648的绝对值
    git 提交信息模板
    rabbitmq at com.rabbitmq.client.impl.Frame.readFrom(Frame.java:91) ~[amqp-client-5.4.3.jar:5.4.3] 错误
    Unity 切换场景的注意点
    Java位运算
  • 原文地址:https://www.cnblogs.com/lhyzdd/p/13989621.html
Copyright © 2011-2022 走看看