OS | 哲学家问题
哲学家进餐问题:
(1) 在什么情况下5 个哲学家全部吃不上饭?
考虑两种实现的方式,如下:
A.算法描述:
void philosopher(int i) {/*i:哲学家编号,从0 到4*/
while (TRUE) {
think( ); /*哲学家正在思考*/
take_fork(i); /*取左侧的筷子*/
take_fork((i+) % N); /*取左侧筷子;%为取模运算*/
eat( ); /*吃饭*/
put_fork(i); /*把左侧筷子放回桌子*/
put_fork((i+) % N); /*把右侧筷子放回桌子*/
}
}
分析:假如所有的哲学家都同时拿起左侧筷子,看到右侧筷子不可用,又都放下左侧筷子,等一会儿,又同时拿起左侧筷子,如此这般,永远重复。对于这种情况,即所有的程序都在无限期地运行,但是都无法取得任何进展,即出现饥饿,所有哲学家都吃不上饭。
B.算法描述:
规定在拿到左侧的筷子后,先检查右面的筷子是否可用。如果不可用,则先放下左侧筷子,等一段时间再重复整个过程。分析:当出现以下情形,在某一个瞬间,所有的哲学家都同时启动这个算法,拿起左侧的筷子,而看到右侧筷子不可用,又都放下左侧筷子,等一会儿,又同时拿起左侧筷子……如此这样永远重复下去。对于这种情况,所有的程序都在运行,但却无法取得进展,即出现饥饿,所有的哲学家都吃不上饭。
(2) 描述一种没有人饿死(永远拿不到筷子)算法。
考虑了四种实现的方式(A、B、C、D):
A.原理:至多只允许四个哲学家同时进餐以保证至少有一个哲学家能够进餐最终总会释放出他所使用过的两支筷子从而可使更多的哲学家进餐。以下将room作为信号量,只允许4个哲学家同时进入餐厅就餐,这样就能保证至少有一个哲学家可以就餐,而申请进入餐厅的哲学家进入room 的等待队列,根据FIFO 的原则,总会进入到餐厅就餐,因此不会出现饿死和死锁的现象。
伪码:
semaphore chopstick[]={,,,,};
semaphore room=;
void philosopher(int i) {
while(true) {
think();
wait(room); //请求进入房间进餐
wait(chopstick[i]); //请求左手边的筷子
wait(chopstick[(i+)%]); //请求右手边的筷子
eat();
signal(chopstick[(i+)%]); //释放右手边的筷子
signal(chopstick[i]); //释放左手边的筷子
signal(room); //退出房间释放信号量room
}
}
B.原理:仅当哲学家的左右两支筷子都可用时才允许他拿起筷子进餐。方法1:利用AND型信号量机制实现:根据课程讲述,在一个原语中,将一段代码同时需要的多个临界资源,要么全部分配给它,要么一个都不分配,因此不会出现死锁的情形。当某些资源不够时阻塞调用进程;由于等待队列的存在,使得对资源的请求满足FIFO 的要求,因此不会出现饥饿的情形。
伪码:
semaphore chopstick[]={,,,,};
void philosopher(int I) {
while(true) {
think();
Swait(chopstick[(I+)]%,chopstick[I]);
eat();
Ssignal(chopstick[(I+)]%,chopstick[I]);
}
}
方法2:利用信号量的保护机制实现。通过信号量mutex对eat()之前的取左侧和右侧筷子的操作进行保护,使之成为一个原子操作,这样可以防止死锁的出现。
伪码:
semaphore mutex = ;
semaphore chopstick[]={,,,,};
void philosopher(int I) {
while(true) {
think();
wait(mutex);
wait(chopstick[(I+)]%);
wait(chopstick[I]);
signal(mutex);
eat();
signal(chopstick[(I+)]%);
signal(chopstick[I]);
}
}
C. 原理:规定奇数号的哲学家先拿起他左边的筷子,然后再去拿他右边的筷子;而偶数号的哲学家则相反.按此规定,将是12号哲学家竞争1号筷子34号哲学家竞争3号筷子.即五个哲学家都竞争奇数号筷子获得后再去竞争偶数号筷子最后总会有一个哲学家能获得两支筷子而进餐。而申请不到的哲学家进入阻塞等待队列,根FIFO原则,则先申请的哲学家会较先可以吃饭,因此不会出现饿死的哲学家。
伪码:
semaphore chopstick[]={,,,,};
void philosopher(int i) {
while(true) {
think();
if(i% == ) {//偶数哲学家,先右后左。
wait (chopstick[ i + ] mod );
wait (chopstick[ i]);
eat();
signal (chopstick[ i + ] mod );
signal (chopstick[ i]);
}
else { //奇数哲学家,先左后右。
wait (chopstick[ i]);
wait (chopstick[ i + ] mod );
eat();
signal (chopstick[ i]);
signal (chopstick[ i + ] mod );
}
}
}
OS | 哲学家问题的更多相关文章
- μC/OS学习资料(附Ebook)
注意:下载地址位于文末. μC/OS-各版本源码 <嵌入式实时操作系统μC/OS-II> <嵌入式实时操作系统μC/OS-III> <μC/OSII2.52源码中文译注- ...
- OS知识点总结
转自:https://blog.csdn.net/csdn_chai/article/details/78002202 1.什么是操作系统? OS是用户与硬件之间的接口,管理计算机的软件和硬件资源. ...
- 菜鸟的飞翔日记-os篇
一轮王道os复习感想 1概述 虽然去年有上操作系统这门必修课,考的成绩也算理想,本来还有点沾沾自喜,嗯,觉得自己学的还不错,知道有一天我拿起了王道,(没给王道打广告)看王道的原因完全在于为考研做准备, ...
- 《Tsinghua os mooc》第17~20讲 同步互斥、信号量、管程、死锁
第十七讲 同步互斥 进程并发执行 好处1:共享资源.比如:多个用户使用同一台计算机. 好处2:加速.I/O操作和CPU计算可以重叠(并行). 好处3:模块化. 将大程序分解成小程序.以编译为例,gcc ...
- [OS] 操作系统课程(三)
工具 源码阅读:understand 源码文档自动生成工具:Doxygen 编译环境:gcc 运行环境:x86机器或QEMU 调试工具:QEMU+(GDB or IDE) IDE:Eclipse-CD ...
- NodeJs之OS
OS Node.js提供了一些基本的底层操作系统的模块OS. API var os = require('os'); console.log('[arch] 操作系统CPU架构'+os.arch()) ...
- Node.js:OS模块
os模块,可以用来获取操作系统相关的信息和机器物理信息,例如操作系统平台,内核,cpu架构,内存,cpu,网卡等信息. 使用如下所示: const os = require('os'); var de ...
- Xamarin+Prism开发详解四:简单Mac OS 虚拟机安装方法与Visual Studio for Mac 初体验
Mac OS 虚拟机安装方法 最近把自己的电脑升级了一下SSD固态硬盘,总算是有容量安装Mac 虚拟机了!经过心碎的安装探索,尝试了国内外的各种安装方法,最后在youtube上找到了一个好方法. 简单 ...
- Mac OS 使用 Vagrant 管理虚拟机(VirtualBox)
Vagrant(官网.github)是一款构建虚拟开发环境的工具,支持 Window,Linux,Mac OS,Vagrant 中的 Boxes 概念类似于 Docker(实质是不同的),你可以把它看 ...
随机推荐
- 利用FFmpeg生成视频缩略图 2.1.8
1.下载FFmpeg文件包,解压包里的\bin\下的文件解压到 D:\ffmpeg\ 目录下. 下载地址 http://ffmpeg.zeranoe.com/builds/win32/static/ ...
- Java for LeetCode 187 Repeated DNA Sequences
All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACG ...
- Java与数据库类型对照表
数据库类型 Java类型 INTEGER int or java.lang.Integer BIGINT long or java.lang.Long SMALLINT short o ...
- Nginx 服务器安装及配置文件详解
原文出处: Sean Chow(@SeanLoook) 欢迎分享原创到伯乐头条 Nginx 在工作中已经有好几个环境在使用了,每次都是重新去网上找博客,各种编译配置,今天自己也整理一份安装文档和 ...
- C# JSON字符串序列化与反序列化常见模型举例
C#中实体转Json常用的类JavaScriptSerializer,该类位于using System.Web.Script.Serialization;命名空间中,添加引用system.web.ex ...
- vijos 1028 LIS *
链接:点我 #include<cstdio> #include<iostream> #include<algorithm> #include<cstring& ...
- adb shell 命令详解(转)
adb介绍 SDK的Tools文件夹下包含着Android模拟器操作的重要命令adb,adb的全称为(Android Debug Bridge就是调试桥的作用.通过adb我们可以在Eclipse中方面 ...
- 使用AIDL远程调用服务中的方法
AIDL:android interface define language(接口定义语言) 作用:方便远程调用其他服务中的方法 注意:安卓四大组件都要在清单文件注册 aidl创建图: AIDL的全称 ...
- 2016.7.8 计算机网络复习要点第四章之地址解析协议ARP
1.地址解析协议ARP:知道一个机器的IP地址,需要找到其相应的硬件地址:ARP协议的用途是为了从网络层使用的IP地址解析出在链路层使用的硬件地址: 2.由于是IP协议使用了ARP协议,因此通常就把A ...
- ember.js:使用笔记7 页面中插入效果
在某些情况下,我们需要根据数据生成某些效果:由于每个模版的controller可能不同,在不同页面之间跳转可能会无法随即更新的问题. controller: 直接使用标签:{{}},适用于在子项目内切 ...