信号量实现哲学家问题(C)

信号量实现哲学家问题©

编号法(打破环路等待条件)

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<semaphore.h>

#define N 5
sem_t chops[N];


void *dine(void *args){
    int i = (int)args;  //哲学家编号0-4
    while(1){
        //哲学家思考
        //对于偶数编号的哲学家,先拿左边筷子,后拿右边筷子
        if(i % 2 == 0){                    
            sem_wait(&chops[i]);         
            sem_wait(&chops[(i + 1) % N]);   
        }
        //对于奇数编号的哲学家,先拿右边筷子,后拿左边筷子
        else{
            sem_wait(&chops[(i + 1) % N]);
            sem_wait(&chops[i]);
        }
        //哲学家用餐中
        printf("%d 号哲学家用餐中...\n",i);
        //用餐完毕后放下筷子
        sem_post(&chops[i]);
        sem_post(&chops[(i + 1) % N]);
        sleep(1);
    }

}

int main(){
    pthread_t philosopher[N];
    for(int i = 0; i < N; i++){
        pthread_create(&philosopher[i],NULL,dine, (void*)i);
        sem_init(&chops[i],0,1);
    }

    for(int i = 0; i < N; i++){
        pthread_join(philosopher[i],NULL);
    }

    for(int i = 0; i < N; i++){
        sem_destroy(&chops[i]);
    }
}

只允许最多4个哲学家入场,避免死锁

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<semaphore.h>

#define N 5 //哲学家个数
#define LEFT i    // i 的左边叉子
#define RIGHT (i + 1) % N       // i 的右边叉子

sem_t chop[N];   //每个筷子信号量为1
sem_t room; //只允许最多4个哲学家入场,打破死锁


//功能:要么拿到两把叉子,要么被阻塞起来
void take_chops(int i){
    sem_wait(&chop[LEFT]);
    sem_wait(&chop[RIGHT]);
}

//用餐完毕,通知左邻右舍
void put_chops(int i){
    sem_post(&chop[LEFT]);
    sem_post(&chop[RIGHT]);
}

//哲学家主代码
void process(void *args){
    int i = (int)args;
    while(1){
        sem_wait(&room);
        //think();
        take_chops(i);
        printf("%d 号哲学家用餐中\n",i);
        //eat()
        put_chops(i);
        sem_post(&room);
        sleep(1);
    }
}

int main(){
    pthread_t philosopher[N];
    sem_init(&room,0,4);
    for(int i = 0; i < N; i++){
        pthread_create(&philosopher[i],NULL,process,(void*)i);
        sem_init(&chop[i],0,1);
    }

    for(int i = 0; i < N; i++){
        pthread_join(philosopher[i],NULL);
    }

    sem_destroy(&room);
    for(int i = 0; i < N; i++){
        sem_destroy(&chop[i]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值