信号量(semaphore),互斥锁(mutex)解决哲学家死锁问题

通过使用信号量机制解决了经典的哲学家就餐死锁问题。每个哲学家尝试获取左右两边的筷子进行就餐,通过限制可用筷子数量避免所有哲学家同时拿起左侧筷子等待右侧筷子的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
author   : youfl
func     : 哲学家吃饭问题
descript :
    哲学家吃饭死锁问题,会产生死锁的主要原因是哲学家会同时拿起左边的筷子
    同时都在等右边的筷子释放,此处可以使用信号量,控制资源数量为总资源数
    量NUM - 1,在已经有NUM - 1 的筷子被使用的情况下,就不能有人再拿左边的
    筷子了进而保证哲学家不能同时获取到左边的筷子,从而解决死锁问题。  

contact:393639665@qq.com


*/
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
//此处是自己用条件变量实现的信号量处理接口,用#include <semaphore.h>替
//代"semaphore_xx.h"即可
#include "semaphore_xx.h"

#define NUM 5
pthread_mutex_t chopsticks[NUM];

using namespace sem_xx;
sem_t semm;

const char * Philosophers[] = {"A","B","C","D","E"};

void * Philosopher(void * p){  
    int * user = new int;
    *user = *(int *)p;
    int left, right;
    left = ((*user) + 5 - 1) % NUM;
    right = ((*user) + 1) %NUM;
   
    while(1){       
        sleep(rand()%5);
        sem_wait(&semm);

        const char * name = Philosophers[(*user)];

        pthread_mutex_lock(chopsticks + left);
        printf("Philosopher %s fetches chopstick %d\n",name, left+1);
        sleep(rand()%2);
        pthread_mutex_lock(chopsticks + right);
        printf("Philosopher %s fetches chopstick %d\n",name, right+1);
        sleep(rand()%5);
        pthread_mutex_unlock(chopsticks + right);
        pthread_mutex_unlock(chopsticks + left);
        printf("Philosopher %s droped chopsticks %d %d\n",name, left+1, right+1);
        sem_post(&semm);
    }
}
int main(){
    int i = 0;
    pthread_t array[NUM];
   
    sem_init(&semm, NUM - 1);
    while(i<NUM)
        pthread_mutex_init(chopsticks + i++, NULL);
       
    for(int j = 0; j<NUM; j++){
        pthread_create(array + j, NULL, &Philosopher, &j);
        sleep(1);
    }
   
    for(int j = 0; j<NUM; j++)
        pthread_join(array[j], NULL);
    return 0;
}

 

ps: "semaphore_xx.h" 见下篇 条件变量实现的信号量处理接口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值