进程(线程)间同步互斥问题(四) 三个烟鬼问题

来源:互联网 发布:小米平板2网络模块坏 编辑:程序博客网 时间:2024/05/16 11:00

问题描述


三个烟鬼问题实际上就是线程的并发问题:

  • 三个烟鬼,一个有烟草,一个有烟纸,一个有火柴
  • 上帝拿走两个人的材料给一个人,那么你那个人可以抽一支烟
  • 当那个人抽完这只烟的时候,上帝重新做决策

题目分析:


-其实就是有前提条件的同步问题:

  • “上帝给材料才能抽烟”
  • “当前抽烟的抽完上帝才能指派下一个人”
  • 同时只会有一个人在抽烟

基本思路:


  • 首先考虑上帝:
    • 上帝指派人的时候,不能有人在抽烟,所以需要一个信号量标记是否有人在抽烟:
      • 1代表当前没有人正在抽烟
      • 0代表当前有人正在抽烟
        - 上帝指派之后会更新一个烟鬼的信号量使它可以抽烟,然后上帝等待烟鬼抽完烟再进行重新指派
  • 烟鬼要等待上帝指派,才能抽烟,所以每个烟鬼有一个信号量
    • 1代表当前有权利抽烟
    • 0代表还需继续等待
    • 抽完烟更新smoking状态唤醒上帝

代码如下:


#include <unistd.h>#include <pthread.h>#include <semaphore.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <time.h>#define TRUE 1#define MAX 3#define p(x) sem_wait(&x)#define v(x) sem_post(&x)sem_t smoker[MAX],smoking;void init ( ){    int i;    for ( i = 0 ; i < MAX ; i++ )        sem_init ( &smoker[i] , 0 , 0 );    sem_init ( &smoking , 0 , 1 );}void* _judge ( ){    while ( TRUE )    {        p(smoking);        int x = (rand()%MAX+MAX)%MAX;        v(smoker[x]);    }}void* _smoker ( void* arg ){    int *p = (int*)arg;    int x = *p;    while ( TRUE )    {       p(smoker[x]);       printf ( "%dth smoker smoking....\n" , x );       sleep(1);       v(smoking);     }}int main ( ){    init ( );    pthread_t sid[MAX],jid;    int sid1[MAX];    int i;    srand ( (unsigned)time(NULL));    pthread_create ( &jid , NULL , _judge , NULL );    for ( i = 0 ; i < MAX; i++ )    {        sid1[i] = i;        pthread_create ( &sid[i] , NULL , _smoker , &sid1[i] );    }    for ( i = 0 ; i < MAX ; i++ )        pthread_join ( sid[i] , NULL );}
0 0
原创粉丝点击