同步:哲学家进餐问题

操作系统实验报告:

一.同步:哲学家进餐问题

1.实验名称:

同步:哲学家进餐问题

2.实验目的:

分析进程争用资源的现象,学习解决进程同步与互斥的方法。

3.实验原理:

五位哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,他们的生活方式是交替的进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐,进餐完毕,放下筷子继续思考。若五位哲学家同时拿起左边的筷子,则因五位哲学家均在等待右边的筷子而使他们饥饿而“死”。解决的办法如下:
至多只允许四位哲学家同时去拿左边的筷子;
仅当哲学家左右两边的筷子均可用时才允许他拿起筷子;
规定奇数号哲学家先拿起他左边的筷子,而偶数号哲学家先拿起他右边的筷子。

4.仪器与材料:

PC机,Devc++。

5.实验步骤(代码):

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
 
#define N 5 // 哲学家的数量
 
sem_t forks[N]; // 信号量数组,表示5个筷子
pthread_t philosophers[N]; // 哲学家线程
sem_t maxDiners; // 最多4个哲学家可以同时进餐
 
void think(int id) {
    printf("哲学家 %d 正在准备\n", id);
    sleep(1); // 假设思考1秒钟
}
 
void eat(int id) {
    printf("哲学家 %d 正在吃饭\n", id);
    sleep(1); // 假设吃饭1秒钟
}
 
void *philosopher(void *num) {
    long id = (long long) num;
    while(1) {
        think(id);
 
        sem_wait(&maxDiners); // 获取吃饭许可
 
        sem_wait(&forks[id]); // 先拿起左边的筷子
        printf("哲学家 %d 拿起左边的筷子 %d\n", id, id);
        sem_wait(&forks[(id+1)%N]); // 再拿起右边的筷子
        printf("哲学家 %d 拿起右边的筷子 %d\n", id, (id+1)%N);
 
        eat(id);
 
        sem_post(&forks[id]); // 放下左边的筷子
        printf("哲学家 %d 放下左边的筷子 %d\n", id, id);
        sem_post(&forks[(id+1)%N]); // 放下右边的筷子
        printf("哲学家 %d 放下右边的筷子 %d\n", id, (id+1)%N);
 
        sem_post(&maxDiners); // 释放吃饭许可
    }
}
 
int main() {
    sem_init(&maxDiners, 0, 4); // 初始化maxDiners信号量为4,表示最多有4个哲学家可以同时吃饭
int i;
    for( i = 0; i < N; i++) {
        sem_init(&forks[i], 0, 1); // 初始化每个信号量为1,表示每个筷子都可用
    }
    for( i = 0; i < N; i++) {
        pthread_create(&philosophers[i], NULL, philosopher, (void*)(long long)i); // 创建哲学家线程
    }
    for( i = 0; i < N; i++) {
        pthread_join(philosophers[i], NULL); // 等待所有哲学家线程结束
    }
    return 0;
}


6.问题即讨论

亦可选择读者-写者、单行轨道、病人就诊、公交车行驶、超市购物、理发师理发等其他问题作为设计对象。

7.运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

强哥哥1222

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值