哲学家就餐问题
哲学家就餐问题
- 问题
- 信号量实现
- 发生死锁版
- 限制人数版
- 规定取筷顺序
- 条件变量实现
问题
在一个圆桌上坐着五位哲学家,每个哲学家面前有一个碗装有米饭的碗和一个筷子。哲学家的生活包括思考和进餐两个活动。当一个哲学家思考时,他不需要任何资源。当他饿了时,他试图拿起两只相邻的筷子来吃饭。由于碗和筷子不能被共享,因此必须找到一种方法来确保哲学家能够安全地进餐,即不会发生死锁(所有哲学家都在等待筷子)也不会发生饥饿(某些哲学家永远无法拿起筷子)
信号量实现
发生死锁版
#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);}
}
相关文章:
哲学家就餐问题
哲学家就餐问题 问题信号量实现发生死锁版限制人数版规定取筷顺序 条件变量实现 问题 在一个圆桌上坐着五位哲学家,每个哲学家面前有一个碗装有米饭的碗和一个筷子。哲学家的生活包括思考和进餐两个活动。当一个哲学家思考时,他不需要任何资源。当他饿了…...
Web安全:SQL注入之布尔盲注原理+步骤+实战操作
「作者简介」:2022年北京冬奥会网络安全中国代表队,CSDN Top100,就职奇安信多年,以实战工作为基础对安全知识体系进行总结与归纳,著作适用于快速入门的 《网络安全自学教程》,内容涵盖系统安全、信息收集等…...
电商秒杀系统-案例04-redis下的session控制
前言: 在现代的Web应用中,安全和高效的用户身份验证机制是至关重要的。本文将深入探讨基于令牌的用户登录会话机制,特别是在使用Redis进行会话管理的情景。通过这一案例实战,我们将了解令牌如何在用户身份验证过程中发挥核心作用&…...
贪吃蛇(c实现)
目录 游戏说明: 第一个是又是封面,第二个为提示信息,第三个是游戏运行界面 游戏效果展示: 游戏代码展示: snack.c test.c snack.h 控制台程序的准备: 控制台程序名字修改: 参考:…...
【论文阅读笔记】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 ,返回 它的 中序 遍历 。 示例 1: 输入:root [1,null,2,3] 输出:[1,3,2]示例 2: 输入:root [] 输出:[]示例 3: 输入:roo…...
云计算十三课
centos安装 点击左上角文件 点击新建虚拟机 点击下一步 点击稍后安装操作系统,下一步 选择Linux(l)下一步 设置虚拟机名称 点击浏览选择安装位置 新建文件夹设置名称不能为中文,点击确定 点击下一步 设置磁盘大小点击下一步…...
[数据集][目标检测]电力场景安全帽检测数据集VOC+YOLO格式295张2类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):295 标注数量(xml文件个数):295 标注数量(txt文件个数):295 标注类别…...
AtCoder Beginner Contest 308 A题 New Scheme
A题:New Scheme 标签:模拟 题意:给定 8 8 8个数的序列,询问这些数是否满足以下条件: 在 100 100 100到 675 675 675之间且能被 25 25 25整除序列是单调非递减的 题解:按题意模拟判断就好了。 代码&#…...
C++编程与朱元墇的关系
学编程和英语没关系,我说这句话,没人会相信,也不会有人说我什么哗众取宠。 我说学编程和朱元墇有关系,一定有人说我放P,其实这个P也和朱元墇有关系, 和朱元墇有什么P关系啊。 真有这P事啊, 朱元…...
0060__设计模式
1. 简单工厂模式( Simple Factory Pattern ) — Graphic Design Patterns 工厂模式 | 菜鸟教程 【设计模式——学习笔记】23种设计模式——建造者模式Builder(原理讲解应用场景介绍案例介绍Java代码实现)-CSDN博客 设计模式—— 五:迪米特…...
【Linux 网络】网络编程套接字 -- 详解
⚪ 预备知识 1、理解源 IP 地址和目的 IP 地址 举例理解:(唐僧西天取经) 在 IP 数据包头部中 有两个 IP 地址, 分别叫做源 IP 地址 和目的 IP 地址。 如果我们的台式机或者笔记本没有 IP 地址就无法上网,而因为…...
编译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,先来体验:(*实验环境账号有效期为1天,到期自动关停,请注意重要数据保护) https://dev.amazoncloud.cn/experience/cloudlab?id65fd86c7ca2a0d291be26068&visi…...
海豚调度器早期版本如何新增worker分组
在DolphinScheduler 1.3.5版本中,Worker分组通常是在部署时通过配置文件进行定义的,而不是在用户界面上直接操作。以下是在DolphinScheduler中新增Worker分组的一般步骤: 修改配置文件: DolphinScheduler的Worker分组信息通常在/…...
Debian Linux 下给Nginx 1.26.0 编译增加Brotli算法支持
明月发现参考【给Nginx添加谷歌Brotli压缩算法支持】一文给出的方法,在Debian Linux 12.5下就一直编译失败,主要的错误是因为文件缺失,在专门又安装了apt-get install libbrotli-dev的依赖库后依然会因为文件缺失无法编译完成,就这…...
中国银行从业在线教育系统,如何搭建网课平台?
如今这个时代相信没多少人是没听过网课平台的,绝大多数人对网课平台的名气是如雷贯耳的。时代的发展,让人们学习的方式变得更加的方便与快捷。今天就来和大家说说网课平台搭建都有哪些方法?网课平台难搭建么? 网课平台搭建的方法,其实网课平…...
解决java.lang.IllegalArgumentException异常的正确方法
java.lang.IllegalArgumentException 是 Java 中的一个异常类,表示方法中传递的参数不合法。这个异常通常在方法被调用时抛出,表明方法的参数出现了问题。要正确解决这个异常,你可以按照以下步骤进行: 查看异常信息:首…...
齿轮滚刀刃口钝化技术简介
介绍 在滚刀的使用中发现,进口滚刀和国产滚刀在加工质量和寿命方面存在显著差异。经过多次比较得知,滚刀的使用寿命可以达到国产滚刀的两倍以上,而进口滚刀返回原厂磨削后的使用寿命约为新刀具的90% ,但同样经过国内厂家磨削后&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/北斗双模定位模块,为开发者提供了强…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
