当前位置: 首页 > news >正文

哲学家就餐问题

哲学家就餐问题

  • 问题
  • 信号量实现
    • 发生死锁版
    • 限制人数版
    • 规定取筷顺序
  • 条件变量实现

问题

在一个圆桌上坐着五位哲学家,每个哲学家面前有一个碗装有米饭的碗和一个筷子。哲学家的生活包括思考和进餐两个活动。当一个哲学家思考时,他不需要任何资源。当他饿了时,他试图拿起两只相邻的筷子来吃饭。由于碗和筷子不能被共享,因此必须找到一种方法来确保哲学家能够安全地进餐,即不会发生死锁(所有哲学家都在等待筷子)也不会发生饥饿(某些哲学家永远无法拿起筷子)

信号量实现

发生死锁版

#include <pthread.h>
#include <semaphore.h>
#include <vector>
#include <unistd.h>
#include <iostream>#define N 5
#define P(x) sem_wait(x)
#define V(x) sem_post(x)sem_t mutex_table;
std::vector<sem_t> mutex_chopsticks(N);void* T_philosopher(void* arg) {int id = *((int*)arg);// id哲学家吃饭需要的2根筷子int lhs = (id + N - 1) % N;int rhs = id % N;while (true) {P(&mutex_chopsticks[lhs]);printf("+ %d by T%d\n", lhs, id);P(&mutex_chopsticks[rhs]);printf("+ %d by T%d\n", rhs, id);// Eat.// Philosophers are allowed to eat in parallel.printf("- %d by T%d\n", lhs, id);printf("- %d by T%d\n", rhs, id);V(&mutex_chopsticks[lhs]);V(&mutex_chopsticks[rhs]);sleep(0.5);}
}int main() {for (int i = 0; i < N; i++) {sem_init(&mutex_chopsticks[i], 0, 1);}std::vector<pthread_t> threads(N);std::vector<int> ids(N);for (int i = 0; i < N; i++) {ids[i] = i + 1;pthread_create(&threads[i], nullptr, &T_philosopher, &ids[i]);}for (int i = 0; i < N; i++) {pthread_join(threads[i], nullptr);}
}

限制人数版

限制最多只能4人同时上桌, 则可以保证至少有一个人可以同时拿起两根筷子

#include <pthread.h>
#include <semaphore.h>
#include <vector>
#include <unistd.h>
#include <iostream>#define P(x) sem_wait(x)
#define V(x) sem_post(x)const int N = 5;sem_t mutex_table;
std::vector<sem_t> mutex_chopsticks(N);void* T_philosopher(void* arg) {int id = *((int*)arg);// id哲学家吃饭需要的2根筷子int lhs = (id + N - 1) % N;int rhs = id % N;while (true) {// Come to mutex_tableP(&mutex_table);P(&mutex_chopsticks[lhs]);printf("+ %d by T%d\n", lhs, id);P(&mutex_chopsticks[rhs]);printf("+ %d by T%d\n", rhs, id);// Eating// Philosophers are allowed to eat in parallel.printf("- %d by T%d\n", lhs, id);printf("- %d by T%d\n", rhs, id);V(&mutex_chopsticks[lhs]);V(&mutex_chopsticks[rhs]);// Leave mutex_tableV(&mutex_table);// Thinkingsleep(0.5);}
}int main() {// 保证任何实际最多只有4个人在桌子上// 这样至少有1个人可以拿到2根筷子sem_init(&mutex_table, 0, N - 1);for (int i = 0; i < N; i++) {sem_init(&mutex_chopsticks[i], 0, 1);}std::vector<pthread_t> threads(N);std::vector<int> ids(N);for (int i = 0; i < N; i++) {ids[i] = i + 1;pthread_create(&threads[i], nullptr, &T_philosopher, &ids[i]);}for (int i = 0; i < N; i++) {pthread_join(threads[i], nullptr);}
}

规定取筷顺序

规定每个人, 先拿编号小的筷子, 再拿编号大的筷子

#include <pthread.h>
#include <semaphore.h>
#include <vector>
#include <unistd.h>
#include <iostream>#define P(x) sem_wait(x)
#define V(x) sem_post(x)const int N = 5;sem_t mutex_table;
std::vector<sem_t> mutex_chopsticks(N);void* T_philosopher(void* arg) {int id = *((int*)arg);// id哲学家吃饭需要的2根筷子int lhs = (id + N - 1) % N;int rhs = id % N;while (true) {// 规定每个人, 先拿编号小的筷子, 再拿编号大的筷子if (lhs < rhs) {P(&mutex_chopsticks[lhs]);P(&mutex_chopsticks[rhs]);} else {P(&mutex_chopsticks[rhs]);P(&mutex_chopsticks[lhs]);}printf("+ %d by T%d\n", lhs, id);printf("+ %d by T%d\n", rhs, id);// Eatingprintf("- %d by T%d\n", lhs, id);printf("- %d by T%d\n", rhs, id);V(&mutex_chopsticks[lhs]);V(&mutex_chopsticks[rhs]);// Thinkingsleep(0.5);}
}int main() {for (int i = 0; i < N; i++) {sem_init(&mutex_chopsticks[i], 0, 1);}std::vector<pthread_t> threads(N);std::vector<int> ids(N);for (int i = 0; i < N; i++) {ids[i] = i + 1;pthread_create(&threads[i], nullptr, &T_philosopher, &ids[i]);}for (int i = 0; i < N; i++) {pthread_join(threads[i], nullptr);}
}

条件变量实现

#include <pthread.h>
#include <vector>
#include <unistd.h>
#include <iostream>#define Lock(x) pthread_mutex_lock(x)
#define UnLock(x) pthread_mutex_unlock(x)const int N = 5;pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
std::vector<int> available(N, true);void* T_philosopher(void* arg) {int id = *((int*)arg);// id哲学家吃饭需要的2根筷子int lhs = (id + N - 1) % N;int rhs = id % N;while (true) {// Come to mutex_tableLock(&mutex);while (!(available[lhs] && available[rhs])) {pthread_cond_wait(&cond, &mutex);}printf("+ %d by T%d\n", lhs, id);printf("+ %d by T%d\n", rhs, id);available[lhs] = available[rhs] = false;UnLock(&mutex);// Eatingsleep(0.5);printf("- %d by T%d\n", lhs, id);printf("- %d by T%d\n", rhs, id);available[lhs] = available[rhs] = true;pthread_cond_broadcast(&cond);// Thinkingsleep(0.5);}
}int main() {std::vector<pthread_t> threads(N);std::vector<int> ids(N);for (int i = 0; i < N; i++) {ids[i] = i + 1;pthread_create(&threads[i], nullptr, &T_philosopher, &ids[i]);}for (int i = 0; i < N; i++) {pthread_join(threads[i], nullptr);}
}

相关文章:

哲学家就餐问题

哲学家就餐问题 问题信号量实现发生死锁版限制人数版规定取筷顺序 条件变量实现 问题 在一个圆桌上坐着五位哲学家&#xff0c;每个哲学家面前有一个碗装有米饭的碗和一个筷子。哲学家的生活包括思考和进餐两个活动。当一个哲学家思考时&#xff0c;他不需要任何资源。当他饿了…...

Web安全:SQL注入之布尔盲注原理+步骤+实战操作

「作者简介」&#xff1a;2022年北京冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础对安全知识体系进行总结与归纳&#xff0c;著作适用于快速入门的 《网络安全自学教程》&#xff0c;内容涵盖系统安全、信息收集等…...

电商秒杀系统-案例04-redis下的session控制

前言&#xff1a; 在现代的Web应用中&#xff0c;安全和高效的用户身份验证机制是至关重要的。本文将深入探讨基于令牌的用户登录会话机制&#xff0c;特别是在使用Redis进行会话管理的情景。通过这一案例实战&#xff0c;我们将了解令牌如何在用户身份验证过程中发挥核心作用&…...

贪吃蛇(c实现)

目录 游戏说明&#xff1a; 第一个是又是封面&#xff0c;第二个为提示信息&#xff0c;第三个是游戏运行界面 游戏效果展示&#xff1a; 游戏代码展示&#xff1a; snack.c test.c snack.h 控制台程序的准备&#xff1a; 控制台程序名字修改&#xff1a; 参考&#xff1a…...

【论文阅读笔记】MapReduce: Simplified Data Processing on Large Clusters

文章目录 1 概念2 编程模型3 实现3.1 MapReduce执行流程3.2 master数据结构3.3 容错机制3.3.1 worker故障3.3.2 master故障3.3.3 出现故障时的语义 3.4 存储位置3.5 任务粒度3.6 备用任务 4 扩展技巧4.1 分区函数4.2 顺序保证4.3 Combiner函数4.4 输入和输出的类型4.5 副作用4.…...

LeetCode题练习与总结:二叉树的中序遍历--94

一、题目描述 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&#xff1a;roo…...

云计算十三课

centos安装 点击左上角文件 点击新建虚拟机 点击下一步 点击稍后安装操作系统&#xff0c;下一步 选择Linux&#xff08;l&#xff09;下一步 设置虚拟机名称 点击浏览选择安装位置 新建文件夹设置名称不能为中文&#xff0c;点击确定 点击下一步 设置磁盘大小点击下一步…...

[数据集][目标检测]电力场景安全帽检测数据集VOC+YOLO格式295张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;295 标注数量(xml文件个数)&#xff1a;295 标注数量(txt文件个数)&#xff1a;295 标注类别…...

AtCoder Beginner Contest 308 A题 New Scheme

A题&#xff1a;New Scheme 标签&#xff1a;模拟 题意&#xff1a;给定 8 8 8个数的序列&#xff0c;询问这些数是否满足以下条件&#xff1a; 在 100 100 100到 675 675 675之间且能被 25 25 25整除序列是单调非递减的 题解&#xff1a;按题意模拟判断就好了。 代码&#…...

C++编程与朱元墇的关系

学编程和英语没关系&#xff0c;我说这句话&#xff0c;没人会相信&#xff0c;也不会有人说我什么哗众取宠。 我说学编程和朱元墇有关系&#xff0c;一定有人说我放P&#xff0c;其实这个P也和朱元墇有关系&#xff0c; 和朱元墇有什么P关系啊。 真有这P事啊&#xff0c; 朱元…...

0060__设计模式

1. 简单工厂模式( Simple Factory Pattern ) — Graphic Design Patterns 工厂模式 | 菜鸟教程 【设计模式——学习笔记】23种设计模式——建造者模式Builder&#xff08;原理讲解应用场景介绍案例介绍Java代码实现&#xff09;-CSDN博客 设计模式—— 五&#xff1a;迪米特…...

【Linux 网络】网络编程套接字 -- 详解

⚪ 预备知识 1、理解源 IP 地址和目的 IP 地址 举例理解&#xff1a;&#xff08;唐僧西天取经&#xff09; 在 IP 数据包头部中 有两个 IP 地址&#xff0c; 分别叫做源 IP 地址 和目的 IP 地址。 如果我们的台式机或者笔记本没有 IP 地址就无法上网&#xff0c;而因为…...

编译OpenResty遇到找不到OpenSSL的解决办法

以OpenResty-1.19.9.1为例 编辑openresty-1.19.9.1/build/nginx-1.19.9/auto/lib/openssl/conf CORE_INCS"$CORE_INCS $OPENSSL/.openssl/include" CORE_DEPS"$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h" CORE_LIBS"$CORE_LIBS $OPENSSL/.…...

Amazon Bedrock 托管 Llama 3 8B70B

Amazon Bedrock 托管 Llama 3 8B&70B&#xff0c;先来体验&#xff1a;&#xff08;*实验环境账号有效期为1天&#xff0c;到期自动关停&#xff0c;请注意重要数据保护&#xff09; https://dev.amazoncloud.cn/experience/cloudlab?id65fd86c7ca2a0d291be26068&visi…...

海豚调度器早期版本如何新增worker分组

在DolphinScheduler 1.3.5版本中&#xff0c;Worker分组通常是在部署时通过配置文件进行定义的&#xff0c;而不是在用户界面上直接操作。以下是在DolphinScheduler中新增Worker分组的一般步骤&#xff1a; 修改配置文件&#xff1a; DolphinScheduler的Worker分组信息通常在/…...

Debian Linux 下给Nginx 1.26.0 编译增加Brotli算法支持

明月发现参考【给Nginx添加谷歌Brotli压缩算法支持】一文给出的方法&#xff0c;在Debian Linux 12.5下就一直编译失败&#xff0c;主要的错误是因为文件缺失&#xff0c;在专门又安装了apt-get install libbrotli-dev的依赖库后依然会因为文件缺失无法编译完成&#xff0c;就这…...

中国银行从业在线教育系统,如何搭建网课平台?

如今这个时代相信没多少人是没听过网课平台的&#xff0c;绝大多数人对网课平台的名气是如雷贯耳的。时代的发展&#xff0c;让人们学习的方式变得更加的方便与快捷。今天就来和大家说说网课平台搭建都有哪些方法?网课平台难搭建么? 网课平台搭建的方法&#xff0c;其实网课平…...

解决java.lang.IllegalArgumentException异常的正确方法

java.lang.IllegalArgumentException 是 Java 中的一个异常类&#xff0c;表示方法中传递的参数不合法。这个异常通常在方法被调用时抛出&#xff0c;表明方法的参数出现了问题。要正确解决这个异常&#xff0c;你可以按照以下步骤进行&#xff1a; 查看异常信息&#xff1a;首…...

齿轮滚刀刃口钝化技术简介

介绍 在滚刀的使用中发现&#xff0c;进口滚刀和国产滚刀在加工质量和寿命方面存在显著差异。经过多次比较得知&#xff0c;滚刀的使用寿命可以达到国产滚刀的两倍以上&#xff0c;而进口滚刀返回原厂磨削后的使用寿命约为新刀具的90% &#xff0c;但同样经过国内厂家磨削后&a…...

【ESP32接入ATK-MO1218 GPS模块】

【ESP32接入ATK-MO1218 GPS模块】 1. 引言2. ATK-MO1218 GPS模块概述3. 接入ATK-MO1218 GPS模块的步骤4. 示例代码5. 结论1. 引言 在现代的嵌入式系统和物联网项目中,精确的位置信息是至关重要的。ATK-MO1218 GPS模块作为一款高性能的GPS/北斗双模定位模块,为开发者提供了强…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...