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

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

  • 相关阅读:
    [原创]平面机器人的避障策略思考
    做个快乐的程序员
    [知识]双音多频(DTMF)信号
    osg 关于LOD
    (3)vtkMapper
    关于坐标系,关于矩阵及线性相关和无关的关系
    osg找不到插件的解决办法
    逆风飞扬,吴仁宏
    整合qt设计师和vs2008出了点问题,记下来
    关于NodeVisitor访问者模式
  • 原文地址:https://www.cnblogs.com/lhyzdd/p/13989621.html
Copyright © 2020-2023  润新知