0
点赞
收藏
分享

微信扫一扫

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


问题描述

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

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

题目分析:

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

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

基本思路:

  • 首先考虑上帝:
  • 上帝指派人的时候,不能有人在抽烟,所以需要一个信号量标记是否有人在抽烟:
  • 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 条评论