c语言管程
⑴ 计算机研究生考试要考哪几门啊
计算机研究生考试要考哪几门啊
自2009年起,计算机专业考研出试为全国统考,2009年计算机考研大纲如下
Ⅰ考查目标
计算机学科专业基础综合考试涵盖数据机构、计算机组成原理、操作系统和计算机网络等学科专业基础课程。要求考生比较系统地掌握上述专业基础课程的概念、基本原理和方法,能够运用所学的基本原理和基本方法分析、判断和解决有关理论问题和实际问题。
Ⅱ考试形式和试卷结构
一、 试卷满分及考试时间
本试卷满分为150分,考试时间为180分钟
二、 答题方式
答题方式为闭卷、笔试
三、 试卷内容结构
数据结构 45分
计算机组成原理 45分
操作系统 35分
计算机网络 25分
四、 试卷题型结构
单项选择题闭简 80分(40小题,每小题2分)
综合应用题 70分
Ⅲ考查范围
数据结构
【考查目标】
1.理解数据结构的基本概念;掌握数据的逻辑结构、存储结构及其差异,以及各种基本操作的实现。
2.掌握基本的数据处理原理和方法的基础上,能够对算法进行设计与分析。
3.能够选择合适的数据结构和方法进行问题求解。
一、线性表
(一)线性表的定义和基本操作
(二)线性表的实现
1.顺序存储结构
2.链式存储结构
3.线性表的应用
二、栈、队列和数组
(一)栈和队列的基本概念
(二)栈和队列的顺序存储结构
(三)栈和队列的链式存储结构
(四)栈和队列的应用
(五)特殊矩阵的压缩存储
三、树与二叉树
(一)树的概念
(二)二叉树
1.二叉树的定义及其主要特征
2.二叉树的顺序存储结构和链式存储结构
3.二叉树的遍历
4.线索二叉树的基本概念和构造
5.二叉排序树
6.平衡二叉树
(三)树、森林
1.书的存储结构
2.森林与二叉树的转换
3.树和森林的遍历
(四)树的应用
1.等价类问题
2.哈夫曼(Huffman)树和哈夫曼编码
四、 图
(一) 图的概念
(二) 图的存储及基本操作
1. 邻接矩阵法
2. 邻接表法
(三) 图的遍历
1. 深度优先搜索
2. 广度优先搜索
(四) 图的基本应用及其复杂度分析
1. 最小(代价)轿迹裤生成树
2. 最短路径
3. 拓扑排序
4. 关键路径
五、 查找
(一) 查找的基本概念
(二) 顺序查找法
(三) 折半查找法
(四) B-树
(五) 散列(Hash)表及其查找
(六) 查找算法的分析及应用
六、 内部排序
(一) 排序的基本概念
(二) 插入排序
1. 直接插入排序
2. 折半插入排序
(三) 气泡排序(bubble sort)
(四)州咐 简单选择排序
(五) 希尔排序(shell sort)
(六) 快速排序
(七) 堆排序
(八) 二路归并排序(merge sort)
(九) 基数排序
(十) 各种内部排序算法的比较
(十一) 内部排序算法的应用
计算机组成原理
【考查目标】
1. 理解单处理器计算机系统中各部件的内部工作原理、组成结构以及相互连接方式,具有完整的计算机系统的整机概念。
2. 理解计算机系统层次化结构概念,熟悉硬件与软件之间的界面,掌握指令集体系结构的基本知识和基本实现方法。
3. 能够运用计算机组成的基本原理和基本方法,对有关计算机硬件系统中的理论和实际问题进行计算、分析,并能对一些基本部件进行简单设计。
一、 计算机系统概述
(一) 计算机发展历程
(二) 计算机系统层次结构
1. 计算机硬件的基本组成
2. 计算机软件的分类
3. 计算机的工作过程
(三) 计算机性能指标
吞吐量、响应时间;cpu时钟周期、主频、CPI、cpu执行时间;MIPS、MFLOPS。
二、 数据的表示和运算
(一) 数制与编码
1. 进位计数制及其相互转换
2. 真值和机器数
3. BCD码
4. 字符与字符串
5. 校验码
(二) 定点数的表示和运算
1. 定点数的表示
无符号数的表示;有符号数的表示。
2. 定点数的运算
定点数的位移运算;原码定点数的加/减运算;补码定点数的加/减运算;定点数的乘/除运算;溢出概念和判别方法。
(三) 浮点数的表示和运算
1. 浮点数的表示
浮点数的表示范围;IEEE754标准
2. 浮点数的加/减运算
(四) 算术逻辑单元ALU
1. 串行加法器和并行加法器
2. 算术逻辑单元ALU的功能和机构
三、 存储器层次机构
(一) 存储器的分类
(二) 存储器的层次化结构
(三) 半导体随机存取存储器
1. SRAM存储器的工作原理
2. DRAM存储器的工作原理
(四) 只读存储器
(五) 主存储器与cpu的连接
(六) 双口RAM和多模块存储器
(七) 高速缓冲存储器(Cache)
1. 程序访问的局部
2. Cache的基本工作原理
3. Cache和主存之间的映射方式
4. Cache中主存块的替换算法
5. Cache写策略
(八) 虚拟存储器
1. 虚拟存储器的基本概念
2. 页式虚拟存储器
3. 段式虚拟存储器
4. 段页式虚拟存储器
5. TLB(快表)
四、 指令系统
(一) 指令格式
1. 指令的基本格式
2. 定长操作码指令格式
3. 扩展操作码指令格式
(二) 指令的寻址方式
1. 有效地址的概念
2. 数据寻址和指令寻址
3. 常见寻址方式
(三) CISC和RISC的基本概念
五、 中央处理器(cpu)
(一) cpu的功能和基本结构
(二) 指令执行过程
(三) 数据通路的功能和基本结构
(四) 控制器的功能和工作原理
1. 硬布线控制器
2. 微程序控制器
微程序、微指令和微命令;微指令的编码方式;微地址的形式方式。
(五) 指令流水线
1. 指令流水线的基本概念
2. 超标量和动态流水线的基本概念
六、 总线
(一) 总线概述
1. 总线的基本概念
2. 总线的分类
3. 总线的组成及性能指标
(二) 总线仲裁
1. 集中仲裁方式
2. 分布仲裁方式
(三) 总线操作和定时
1. 同步定时方式
2. 异步定时方式
(四) 总线标准
七、 输入输出(I/O)系统
(一) I/O系统基本概念
(二) 外部设备
1. 输入设备:键盘、鼠标
2. 输出设备:显示器、打印机
3. 外存储器:硬盘存储器、磁盘阵列、光盘存储器
(三) I/O接口(I/O控制器)
1. I/O接口的功能和基本结构
2. I/O端口及其编址
(四) I/O方式
1. 程序查询方式
2. 程序中断方式
中断的基本概念;中断响应过程;中断处理过程;多重中断和中断屏蔽的概念。
3. DMA方式
DMA控制器的组成;DMA传送过程。
4. 通道方式
操作系统
【考查目标】
1. 了解操作系统在计算机系统中的作用、地位、发展和特点。
2. 理解操作系统的基本概念、原理,掌握操作系统设计方法与实现技术。
3. 能够运用所学的操作系统原理、方法与技术分析问题和解决问题。
一、 操作系统概述
(一) 操作系统的概念、特征、功能和提供的服务
(二) 操作系统的发展与分类
(三) 操作系统的运行环境
二、 进程管理
(一) 进程与线程
1. 进程概念
2. 进程的状态与转换
3. 进程控制
4. 进程组织
5. 进程通信
共享存储系统;消息传递系统;管道通信。
6.线程概念与多线程模型
(二)处理机调度
1.调度的基本概念
2.调度时机、切换与过程
3.调度的基本准则
4.调度方式
5.典型调度算法
先来先服务调度算法;短作业(短任务、短进程、短线程)优先调度算法;时间片轮转调度算法;优先级调度算法;高响应比优先调度算法;多级反馈队列调度算法。
(三)进程同步
1. 进程同步的基本概念
2. 实现临界区互斥的基本方法
软件实现方法;硬件实现方法。
3. 信号量
4. 管程
5. 经典同步问题
生产者-消费者问题;读者-写者问题;哲学家进餐问题。
(四) 死锁
1. 死锁的概念
2. 死锁处理策略
3. 死锁预防
4. 死锁避免
系统安全状态:银行家算法。
5. 死锁检测和解除
三、 内存管理
(一) 内存管理基础
1. 内存管理概念
程序装入与链接;逻辑地址与物理地址空间;内存保护。
2. 交换与覆盖
3. 连续分配管理方式
单一连续分配;分区分配。
4. 非连续分配管理方式
分页管理方式;分段管理方式;段页式管理方式。
(二) 虚拟内存管理
1. 虚拟内存基本概念
2. 请求分页管理方式
3. 页面置换算法
最佳置换算法(OPT);先进先出置换算法(FIFO);最近最少使用置换算法(LRU);时钟置换算法(CLOCK)。
4. 页面分配策略
5. 抖动
抖动现象;工作集。
6. 请求分段管理方式
7. 请求段页式管理方式
四、 文件管理
(一) 文件系统基础
1. 文件概念
2. 文件结构
顺序文件;索引文件;索引顺序文件。
3. 目录结构
文件控制块和索引节点;单级目录结构和两级目录结构;树形目录结构;图形目录结构。
4. 文件共享
共享动机;共享方式;共享语义。
5. 文件保护
访问类型;访问控制。
(二) 文件系统实现
1. 文件系统层次结构
2. 目录实现
3. 文件实现
(三) 磁盘组织与管理
1. 磁盘的结构
2. 磁盘调度算法
3. 磁盘的管理
五、 输入输出(I/O)管理
(一) I/O管理概述
1. I/O设备
2. I/O管理目标
3. I/O管理功能
4. I/O应用接口
5. I/O控制方式
(二) I/O核心子系统
1. I/O调度概念
2. 高速缓存与缓冲区
3. 设备分配与回收
4. 假脱机技术(SPOOLing)
5. 出错处理
计算机网络
【考查目标】
1. 掌握计算机网络的基本概念、基本原理和基本方法。
2. 掌握计算机网络的体系结构和典型网络协议,了解典型网络设备的组成和特点,理解典型网络设备的工作原理
3. 能够运用计算机网络的基本概念、基本原理和基本方法进行网络系统的分析、设计和应用
一、 计算机网络体系结构
(一) 计算机网络概述
1. 计算机网络的概念、组成与功能
2. 计算机网络的分类
3. 计算机网络与互联网的发展历史
4. 计算机网络的标准化工作及相关组织
(二) 计算机网络体系结构与参考模型
1. 计算机网络分层结构
2. 计算机网络协议、接口、服务等概念
3. ISO/OSI参考模型和TCP/IP模型
二、 物理层
(一) 通信基础
1. 信道、信号、宽带、码元、波特、速率等基本概念
2. 奈奎斯特定理与香农定理
3. 信源与信宿
4. 编码与调制
5. 电路交换、报文交换与分组交换
6. 数据报与虚电路
(二) 传输介质
1. 双绞线、同轴电缆、光纤与无线传输介质
2. 物理层接口的特性
(三) 物理层设备
1. 中继器
2. 集线器
三、 数据链路层
(一) 数据链路层的功能
(二) 组帧
(三) 差错控制
1. 检错编码
2. 纠错编码
(四) 流量控制与可靠传输机制
1. 流量控制
可靠传输与滑轮窗口机制
2. 单帧滑动窗口与停止-等待协议
3. 多帧滑动窗口与后退N帧协议(GBN)
4. 多帧滑动窗口与选择重传协议(SR)
(五) 介质访问控制
1. 信道划分介质访问控制
频分多路复用、时分多路复用、波分多路复用、码分多路复用的概念和基本原理。
2. 随即访问介质访问控制
ALOHA协议;CSMA协议;CSMA/CD协议;CSMA/CA协议。
3. 轮询访问介质访问控制:令牌传递协议
(六) 局域网
1. 局域网的基本概念与体系结构
2. 以太网与IEEE 802.3
3. IEEE 802.11
4. 令牌环网的基本原理
(七) 广域网
1. 广域网的基本概念
2. PPP协议
3. HDLC协议
4. ATM网络基本原理
(八) 数据链路层设备
1. 网桥
网桥的概念;透明网桥与生成树算饭;源选径网桥与源选径算法。
2. 局域网交换机及其工作原理。
四、 网络层
(一) 网络层的功能
1. 异构网络互联
2. 路由与转发
3. 拥塞控制
(二) 路由算法
1. 静态路由与动态路由
2. 距离-向量路由算法
3. 链路状态路由算法
4. 层次路由
(三) IPv4
1. IPv4分组
2. IPv4地址与NAT
3. 子网划分与子网掩码、CIDR
4. ARP协议、DHCP协议与ICMP协议
(四) IPv6
1. IPv6的主要特点
2. IPv6地址
(五) 路由协议
1. 自治系统
2. 域内路由与域间路由
3. RIP路由协议
4. OSPF路由协议
5. BGP路由协议
(六) IP组播
1. 组播的概念
2. IP组播地址
3. 组播路由算法
(七) 移动IP
1. 移动IP的概念
2. 移动IP的通信过程
(八) 网络层设备
1. 路由器的组成和功能
2. 路由表与路由转发
五、 传输层
(一) 传输层提供的服务
1. 传输层的功能
2. 传输层寻址与端口
3. 无连接服务与面向连接服务
(二) UDP协议
1. UDP数据报
2. UDP校验
(三) TCP协议
1. TCP段
2. TCP连接管理
3. TCP可靠传输
4. TCP流量控制与拥塞控制
六、 应用层
(一) 网络应用模型
1. 客户/服务器模型
2. P2P模型
(二) DNS系统
1. 层次域名空间
2. 域名服务器
3. 域名解析过程
(三) FTP
1. FTP协议的工作原理
2. 控制连接与数据连接
(四) 电子邮件
1. 电子邮件系统的组成结构
2. 电子邮件格式与MIME
3. SMTP协议与POP3协议
(五)
1. 的概念与组成结构
HTTP协议
我学的是计算机专业,在学大纲中涉及的课程前先修了高等数学,离散数学,c语言,C++,在调试数据结构和操作系统的程序时用的都是C
求2012年计算机研究生考试题
网上很多可以下载
河南大学计算机研究生考哪几门
1、河南大学计算机研究生考
①101思想政治理论
②201英语一
③602微积分
④840专业基础课(数据结构、操作系统)
2、建议去河南大学官网查看专业目录等考研信息,或者网络搜索《河南大学2014年硕士研究生招生专业目录》即可了解,务必以报考当年9月份学校官网发布的考研信息为准。
计算机研究生考试科目有那些?
计算机大部分院校的考试科目代码为408,国家统一命题。主要四部分,参考书目:
一、数据结构
严蔚敏、吴伟民编着:《数据结构(c语言版)》,清华大学出版社
二、计算机组成原理
唐朔飞编着:《计算机组成原理》,高等教育出版社,1999年版
白中英主编:《计算机组成原理》,科学出版社
三、操作系统
汤小丹、梁红兵、哲凤屏、汤子瀛编着:《计算机操作系统(第三版)》,西安电子科技大学出版社
四、计算机网络
谢希仁编着:《计算机网络(第5版)》,电子工业出版社
高传善、毛迪林、曹袖主编:《数据通信与计算机网络(第2版)》,高等教育出版社
全国硕士研究生入学统一考试计算机专业基础综合考试大纲解析,高等教育出版社,这个大纲解析是必备的。
有不参加统考的学校,学校自主命题,考试科目及参考书目去目标院校的研究生网站查找下。
考计算机研究生需要靠那几门?
⑵ 哲学家就餐问题的算法实现
操作系统并发和互斥:哲学家进餐问题和理发师问题
1. 哲学家进餐问题:
(1) 在什么情况下5 个哲学家全部吃不上饭?
考虑两种实现的方式,如下:
A.
算法描述:
void philosopher(int i) /*i:哲学家编号,从0 到4*/
{
while (TRUE) {
think( ); /*哲学家正在思考*/
take_fork(i); /*取左侧的筷子*/
take_fork((i+1) % N); /*取左侧筷子;%为取模运算*/
eat( ); /*吃饭*/
put_fork(i); /*把左侧筷子放回桌子*/
put_fork((i+1) % N); /*把右侧筷子放回桌子*/
}
}
分析:假如所有的哲学家都同时拿起左侧筷子,看到右侧筷子不可用,又都放下左侧筷子,
等一会儿,又同时拿起左侧筷子,如此这般,永远重复。对于这种情况,即所有的程序都在
无限期地运行,但是都无法取得任何进展,即出现饥饿,所有哲学家都吃不上饭。
B.
算法描述:
规定在拿到左侧的筷子后,先检查右面的筷子是否可用。如果不可用,则先放下左侧筷子,
等一段时间再重复整个过程。
分析:当出现以下情形,在某一个瞬间,所有的哲学家都同时启动这个算法,拿起左侧的筷
子,而看到右侧筷子不可用,又都放下左侧筷子,等一会儿,又同时拿起左侧筷子……如此
这样永远重复下去。对于这种情况,所有的程序都在运行,但却无法取得进展,即出现饥饿,
所有的哲学家都吃不上饭。
(2) 描述一种没有人饿死(永远拿不到筷子)算法。
考虑了四种实现的方式(A、B、C、D):
A.原理:至多只允许四个哲学家同时进餐,以保证至少有一个哲学家能够进餐,最终总会释
放出他所使用过的两支筷子,从而可使更多的哲学家进餐。以下将room 作为信号量,只允
许4 个哲学家同时进入餐厅就餐,这样就能保证至少有一个哲学家可以就餐,而申请进入
餐厅的哲学家进入room 的等待队列,根据FIFO 的原则,总会进入到餐厅就餐,因此不会
出现饿死和死锁的现象。
伪码:
semaphore chopstick[5]={1,1,1,1,1};
semaphore room=4;
void philosopher(int i)
{
while(true)
{
think();
wait(room); //请求进入房间进餐
wait(chopstick[i]); //请求左手边的筷子
wait(chopstick[(i+1)%5]); //请求右手边的筷子
eat();
signal(chopstick[(i+1)%5]); //释放右手边的筷子
signal(chopstick[i]); //释放左手边的筷子
signal(room); //退出房间释放信号量room
}
}
B.原理:仅当哲学家的左右两支筷子都可用时,才允许他拿起筷子进餐。
方法1:利用AND 型信号量机制实现:根据课程讲述,在一个原语中,将一段代码同时需
要的多个临界资源,要么全部分配给它,要么一个都不分配,因此不会出现死锁的情形。当
某些资源不够时阻塞调用进程;由于等待队列的存在,使得对资源的请求满足FIFO 的要求,
因此不会出现饥饿的情形。
伪码:
semaphore chopstick[5]={1,1,1,1,1};
void philosopher(int I)
{
while(true)
{
think();
Swait(chopstick[(I+1)]%5,chopstick[I]);
eat();
Ssignal(chopstick[(I+1)]%5,chopstick[I]);
}
}
方法2:利用信号量的保护机制实现。通过信号量mutex对eat()之前的取左侧和右侧筷
子的操作进行保护,使之成为一个原子操作,这样可以防止死锁的出现。
伪码:
semaphore mutex = 1 ;
semaphore chopstick[5]={1,1,1,1,1};
void philosopher(int I)
{
while(true)
{
think();
wait(mutex);
wait(chopstick[(I+1)]%5);
wait(chopstick[I]);
signal(mutex);
eat();
signal(chopstick[(I+1)]%5);
signal(chopstick[I]);
}
}
C. 原理:规定奇数号的哲学家先拿起他左边的筷子,然后再去拿他右边的筷子;而偶数号
的哲学家则相反.按此规定,将是1,2号哲学家竞争1号筷子,3,4号哲学家竞争3号筷子.即
五个哲学家都竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总会有一个哲学家能获
得两支筷子而进餐。而申请不到的哲学家进入阻塞等待队列,根FIFO原则,则先申请的哲
学家会较先可以吃饭,因此不会出现饿死的哲学家。
伪码:
semaphore chopstick[5]={1,1,1,1,1};
void philosopher(int i)
{
while(true)
{
think();
if(i%2 == 0) //偶数哲学家,先右后左。
{
wait (chopstick[ i + 1 ] mod 5) ;
wait (chopstick[ i]) ;
eat();
signal (chopstick[ i + 1 ] mod 5) ;
signal (chopstick[ i]) ;
}
Else //奇数哲学家,先左后右。
{
wait (chopstick[ i]) ;
wait (chopstick[ i + 1 ] mod 5) ;
eat();
signal (chopstick[ i]) ;
signal (chopstick[ i + 1 ] mod 5) ;
}
}
D.利用管程机制实现(最终该实现是失败的,见以下分析):
原理:不是对每只筷子设置信号量,而是对每个哲学家设置信号量。test()函数有以下作
用:
a. 如果当前处理的哲学家处于饥饿状态且两侧哲学家不在吃饭状态,则当前哲学家通过
test()函数试图进入吃饭状态。
b. 如果通过test()进入吃饭状态不成功,那么当前哲学家就在该信号量阻塞等待,直到
其他的哲学家进程通过test()将该哲学家的状态设置为EATING。
c. 当一个哲学家进程调用put_forks()放下筷子的时候,会通过test()测试它的邻居,
如果邻居处于饥饿状态,且该邻居的邻居不在吃饭状态,则该邻居进入吃饭状态。
由上所述,该算法不会出现死锁,因为一个哲学家只有在两个邻座都不在进餐时,才允
许转换到进餐状态。
该算法会出现某个哲学家适终无法吃饭的情况,即当该哲学家的左右两个哲学家交替
处在吃饭的状态的时候,则该哲学家始终无法进入吃饭的状态,因此不满足题目的要求。
但是该算法能够实现对于任意多位哲学家的情况都能获得最大的并行度,因此具有重要
的意义。
伪码:
#define N 5 /* 哲学家人数*/
#define LEFT (i-1+N)%N /* i的左邻号码 */
#define RIGHT (i+1)%N /* i的右邻号码 */
typedef enum { THINKING, HUNGRY, EATING } phil_state; /*哲学家状态*/
monitor dp /*管程*/
{
phil_state state[N];
semaphore mutex =1;
semaphore s[N]; /*每个哲学家一个信号量,初始值为0*/
void test(int i)
{
if ( state[i] == HUNGRY &&state[LEFT(i)] != EATING &&
state[RIGHT(i)] != EATING )
{
state[i] = EATING;
V(s[i]);
}
}
void get_forks(int i)
{
P(mutex);
state[i] = HUNGRY;
test(i); /*试图得到两支筷子*/
V(mutex);
P(s[i]); /*得不到筷子则阻塞*/
}
void put_forks(int i)
{
P(mutex);
state[i]= THINKING;
test(LEFT(i)); /*看左邻是否进餐*/
test(RIGHT(i)); /*看右邻是否进餐*/
V(mutex);
}
}
哲学家进程如下:
void philosopher(int process)
{
while(true)
{
think();
get_forks(process);
eat();
put_forks(process);
}
}
2.理发师问题:一个理发店有一个入口和一个出口。理发店内有一个可站5 位顾客的站席
区、4 个单人沙发、3 个理发师及其专用理发工具、一个收银台。新来的顾客坐在沙发上等
待;没有空沙发时,可在站席区等待;站席区满时,只能在入口外等待。理发师可从事理
发、收银和休息三种活动。理发店的活动满足下列条件:
1)休息的理发师是坐地自己专用的理发椅上,不会占用顾客的沙发;
2)处理休息状态的理发师可为在沙发上等待时间最长的顾客理发;
3)理发时间长短由理发师决定;
4)在站席区等待时间最长的顾客可坐到空闲的理发上;
5)任何时刻最多只能有一个理发师在收银。
试用信号量机制或管程机制实现理发师进程和顾客进程。
原理:
(1)customer 进程:
首先检查站席区是否已满(stand_capacity),若满选择离开,否则进入站席区,即进入
理发店。在站席区等待沙发的空位(信号量sofa),如果沙发已满,则进入阻塞等待队列,
直到出现空位,在站席区中等待时间最长的顾客离开站席区(stand_capacity)。坐到沙
发上,等待理发椅(barber_chair),如果理发椅已满,则进入阻塞等待队列,直到出现
空位,在沙发上等待时间最长的顾客离开沙发(释放信号量sofa)。坐到理发椅上,释放
准备好的信号(customer_ready),获得该理发师的编号(0~1 的数字)。等待理发师理
发结束(finished[barber_number])。在离开理发椅之前付款(payment),等待收据
(receipt),离开理发椅(leave_barberchair)。最后离开理发店。
这里需要注意几点:
a) 首先是几个需要进行互斥处理的地方,主要包括:进入站席区、进入沙发、进入理发椅
和付款几个地方。
b) 通过barber_chair 保证一个理发椅上最多只有一名顾客。但这也不够,因为单凭
baber_chair 无法保证一名顾客离开理发椅之前,另一位顾客不会坐到该理发椅上,
因此增加信号量leave_barberchair,让顾客离开理发椅后,释放该信号,而理发
师接收到该信号后才释放barber_chair 等待下一位顾客。
c) 在理发的过程中,需要保证是自己理发完毕,才能够进行下面的付款、离开理发椅的活
动。这个机制是通过customer 进程获得给他理发的理发师编号来实现的,这样,当
该编号的理发师释放对应的finished[i]信号的时候,该顾客才理发完毕。
d) 理发师是通过mutex 信号量保证他们每个人同时只进行一项操作(理发或者收款)。
e) 为了保证该顾客理发完毕后马上可以付款离开,就应该保证给该顾客理发的理发师在理
发完毕后马上到收银台进入收款操作而不是给下一位顾客服务。在伪码中由以下机制实
现:即顾客在释放离开理发椅的信号前,发出付款的信号。这样该理发师得不到顾客的
离开理发椅的信号,不能进入下一个循环为下一名顾客服务,而只能进入收款台的收款
操作。直到顾客接到收据后,才释放离开理发椅的信号,离开理发椅,让理发师释放该
理发椅的信号,让下一位等待的顾客坐到理发椅上。
(2)barber 进程
首先将该理发师的编号压入队列,供顾客提取。等待顾客坐到理发椅坐好(信号量
customer_ready),开始理发,理发结束后释放结束信号(finished[i])。等待顾客
离开理发椅(leave_barberchair)(期间去收银台进行收款活动),释放理发椅空闲信
号(barber_chair),等待下一位顾客坐上来。
(3)cash(收银台)进程
等待顾客付款(payment),执行收款操作,收款操作结束,给付收据(receipt)。
信号量总表:
信号量 wait signal
stand_capacity 顾客等待进入理发店 顾客离开站席区
sofa 顾客等待坐到沙发 顾客离开沙发
barber_chair 顾客等待空理发椅 理发师释放空理发椅
customer_ready 理发师等待,直到一个顾客坐
到理发椅
顾客坐到理发椅上,给理发师
发出信号
mutex 等待理发师空闲,执行理发或
收款操作
理发师执行理发或收款结束,
进入空闲状态
mutex1 执行入队或出队等待 入队或出队结束,释放信号
finished[i] 顾客等待对应编号理发师理
发结束
理发师理发结束,释放信号
leave_barberchair 理发师等待顾客离开理发椅 顾客付款完毕得到收据,离开
理发椅释放信号
payment 收银员等待顾客付款 顾客付款,发出信号
receipt 顾客等待收银员收、开具收据收银员收款结束、开具收据,
释放信号
伪码:
semaphore stand_capacity=5;
semaphore sofa=4;
semaphore barber_chair=3;
semaphore customer_ready=0;
semaphore mutex=3;
semaphore mutex1=1;
semaphore finished[3]={0,0,0};
semaphore leave_barberchair=0;
semaphore payment=0;
semaphore receipt=0;
void customer()
{
int barber_number;
wait(stand_capacity); //等待进入理发店
enter_room(); //进入理发店
wait(sofa); //等待沙发
leave_stand_section(); //离开站席区
signal(stand_capacity);
sit_on_sofa(); //坐在沙发上
wait(barber_chair); //等待理发椅
get_up_sofa(); //离开沙发
signal(sofa);
wait(mutex1);
sit_on_barberchair(); //坐到理发椅上
signal(customer_ready);
barber_number=dequeue(); //得到理发师编号
signal(mutex1);
wait(finished[barber_number]); //等待理发结束
pay(); //付款
signal(payment); //付款
wait(receipt); //等待收据
get_up_barberchair(); //离开理发椅
signal(leave_barberchair); //发出离开理发椅信号
exit_shop(); //了离开理发店
}
void barber(int i)
{
while(true)
{
wait(mutex1);
enqueue(i); //将该理发师的编号加入队列
signal(mutex1);
wait(customer_ready); //等待顾客准备好
wait(mutex);
cut_hair(); //理发
signal(mutex);
signal(finished[i]); //理发结束
wait(leave_barberchair); //等待顾客离开理发椅信号
signal(barber_chair); //释放barber_chair 信号
}
}
void cash() //收银
{
while(true)
{
wait(payment); //等待顾客付款
wait(mutex); //原子操作
get_pay(); //接受付款
give_receipt(); //给顾客收据
signal(mutex);
signal(receipt); //收银完毕,释放信号
}
}
分析:
在分析该问题过程中,出现若干问题,是参阅相关资料后才认识到这些问题的隐蔽性和严重
性的,主要包括:
(1)在顾客进程,如果是在释放leave_barberchair 信号之后进行付款动作的话,很
容易造成没有收银员为其收款的情形, 原因是: 为该顾客理发的理发师收到
leave_barberchair 信号后,释放barber_chair 信号,另外一名顾客坐到理发椅上,
该理发师有可能为这另外一名顾客理发,而没有为刚理完发的顾客收款。为解决这个问题,
就是采取在释放leave_barberchair 信号之前,完成付款操作。这样该理发师无法进入
下一轮循环为另外顾客服务,只能到收银台收款。
(2)本算法是通过给理发师编号的方式,当顾客坐到某理发椅上也同时获得理发师的编号,
如此,当该理发师理发结束,释放信号,顾客只有接收到为其理发的理发师的理发结束信号
才会进行付款等操作。这样实现,是为避免这样的错误,即:如果仅用一个finished 信
号量的话,很容易出现别的理发师理发完毕释放了finished 信号,把正在理发的这位顾
客赶去付款,而已经理完发的顾客却被阻塞在理发椅上的情形。当然也可以为顾客进行编
号,让理发师获取他理发的顾客的编号,但这样就会限制顾客的数量,因为finished[]
数组不能是无限的。而为理发师编号,则只需要三个元素即可。
3.参考文献:
左金平 计算机操作系统中哲学家进餐问题探究。
参考教材 操作系统—内核与设计原理
⑶ 如何利用管程来解决哲学家进餐问题
利用管程机制实现(最终该实现是失败的,见以下分析):
原理:不是对每只筷子设置信号量,而是对每个哲学家设置信号量。test()函数有以下作
用:
a. 如果当前处理的哲学家处于饥饿状态且两侧哲学家不在吃饭状态,则当前哲学家通过
test()函数试图进入吃饭状态。
b. 如果通过test()进入吃饭状态不成功,那么当前哲学家就在该信号量阻塞等待,直到
其他的哲学家进程通过test()将该哲学家的状态设置为EATING。
c. 当一个哲学家进程调用put_forks()放下筷子的时候,会通过test()测试它的邻居,
如果邻居处于饥饿状态,且该邻居的邻居不在吃饭状态,则该邻居进入吃饭状态。
由上所述,该算法不会出现死锁,因为一个哲学家只有在两个邻座都不在进餐时,才允
许转换到进餐状态。
该算法会出现某个哲学家适终无法吃饭的情况,即当该哲学家的左右两个哲学家交替
处在吃饭的状态的时候,则该哲学家始终无法进入吃饭的状态,因此不满足题目的要求。
但是该算法能够实现对于任意多位哲学家的情况都能获得最大的并行度,因此具有重要
的意义。
伪码:
#define N 5 /* 哲学家人数*/
#define LEFT (i-1+N)%N /* i的左邻号码 */
#define RIGHT (i+1)%N /* i的右邻号码 */
typedef enum { THINKING, HUNGRY, EATING } phil_state; /*哲学家状态*/
monitor dp /*管程*/
{
phil_state state[N];
semaphore mutex =1;
semaphore s[N]; /*每个哲学家一个信号量,初始值为0*/
void test(int i)
{
if ( state[i] == HUNGRY &&state[LEFT(i)] != EATING &&
state[RIGHT(i)] != EATING )
{
state[i] = EATING;
V(s[i]);
}
}
void get_forks(int i)
{
P(mutex);
state[i] = HUNGRY;
test(i); /*试图得到两支筷子*/
V(mutex);
P(s[i]); /*得不到筷子则阻塞*/
}
void put_forks(int i)
{
P(mutex);
state[i]= THINKING;
test(LEFT(i)); /*看左邻是否进餐*/
test(RIGHT(i)); /*看右邻是否进餐*/
V(mutex);
}
}
哲学家进程如下:
void philosopher(int process)
{
while(true)
{
think();
get_forks(process);
eat();
put_forks(process);
}
}
有更好的答案尽快转给你
⑷ 怎么用c语言编程 实现创建原语、撤销原语、阻塞原语和唤醒原语
下,应该差不多
一、如何建立线程
用到的头文件
(a)pthread.h
(b)semaphore.h
(c) stdio.h
(d)string.h
定义线程标识
pthread_t
创建线程
pthread_create
对应了一个函数作为线程的程序段
注意的问题
要保证进程不结束(在创建线程后加死循环)
在线程中加入While(1)语句,也就是死循环,保证进程不结束。
二、控制线程并发的函数
sem_t:信号量的类型
sem_init:初始化信号量
sem_wait:相当于P操作
sem_post:相当于V操作
三、实现原形系统
父亲、母亲、儿子和女儿的题目:
桌上有一只盘子,每次只能放入一只水果。爸爸专放苹果,妈妈专放橘子,一个儿子专等吃盘子中的橘子,一个女儿专等吃盘子中的苹果。分别用P,V操作和管程实现
每个对应一个线程
pthread_t father; father进程
pthread_t mother; mother进程
pthread_t son; son进程
pthread_t daughter; daughter进程
盘子可以用一个变量表示
sem_t empty;
各线程不是只做一次,可以是无限或有限次循环
用While(1)控制各线程无限次循环
输出每次是那个线程执行的信息
printf("%s\n",(char *)arg);通过参数arg输出对应线程执行信息
编译方法
gcc hex.c -lpthread
生成默认的可执行文件a.out
输入./a.out命令运行
查看结果:程序连续运行显示出
father input an apple.
daughter get an apple.
mother input an orange.
son get an orange.
mother input an orange.
son get an orange.
………………..
四、程序源代码
#include <stdio.h>
#include<string.h>
#include <semaphore.h>
#include <pthread.h>
sem_t empty; //定义信号量
sem_t applefull;
sem_t orangefull;
void *procf(void *arg) //father线程
{
while(1){
sem_wait(&empty); //P操作
printf("%s\n",(char *)arg);
sem_post(&applefull); //V操作
sleep(7);
}
}
void *procm(void *arg) //mother线程
{
while(1){
sem_wait(&empty);
printf("%s\n",(char *)arg);
sem_post(&orangefull);
sleep(3);
}
}
void *procs(void *arg) //son线程
{
while(1){
sem_wait(&orangefull);
printf("%s\n",(char *)arg);
sem_post(&empty);
sleep(2);
}
}
void *procd(void *arg) //daughter线程
{
while(1){
sem_wait(&applefull);
printf("%s\n",(char *)arg);
sem_post(&empty);
sleep(5);
}
}
main()
{
pthread_t father; //定义线程
pthread_t mother;
pthread_t son;
pthread_t daughter;
sem_init(&empty, 0, 1); //信号量初始化
sem_init(&applefull, 0, 0);
sem_init(&orangefull, 0, 0);
pthread_create(&father,NULL,procf,"father input an apple."); //创建线程
pthread_create(&mother,NULL,procm,"mother input an orange.");
pthread_create(&daughter,NULL,procd,"daughter get an apple.");
pthread_create(&son,NULL,procs,"son get an orange.");
while(1){} //循环等待
}
另外,站长团上有产品团购,便宜有保证
⑸ 计算机科学与技术考研大纲及考研书籍
考研计算机科学与技术大纲及书籍,
不同的院校会有不同的要求的,
这个问题问得我们不知如何作答才好啊,
比如:重庆大学081200计算机科学与技术考研参考书目如下:
917计算机学科专业基础综合
[1]DavidA.PattersonJohnL.Hennessy.计算机组成与设计:硬件/软件接口(原书第4版)[M].北京:机械工业出版社,2012.
[2]严蔚敏,吴伟民.数据结构(C语言版本)[M].北京:清华大学出版社,2004.
[3]张尧学,史美林,张高.计算机操作系统教程[M].北京:清华大学出版社,2006(3).
内蒙古大学计算机科学与技术考研:
893 数据结构与操虚燃磨作系统(自命题) ,
《数据结构与算法》赵玉兰,清华大学出版社,
《计算机操作系差斗统》第三版,汤段桐小丹,西安电子科技大学出版社
⑹ 管程的wait操作和信号量的wait操作有什么区别
wait(s) 就是s减1
如果原来是0
那么就是wait(0)
还记枝盯得C语仿则言中的while吗 while(0)就是不进入循环 一直等到while(1)再进入循环
(可以这么理解,但猛大和实际while直接不执行循环里的语句,跳过去了)
如果原来>0
直接减1,s的资源少了一个
如果原来
⑺ 计算机研究生考试要考哪几门啊
计算机历年考研真题
链接:https://pan..com/s/1S0XYQQBxtaFkIAOpoymp9Q
提取码:cugd
若资租型源有疑弊模猜问欢迎追问码蚂
⑻ linux管程实验报告 c 语言的
神马东东?
⑼ C语言内存申请(两个线程并发)
这是一个操作系统中进程同步典型的消竖喊费者-生产者问题,一般的解法就是按照你这样来做,给缓冲区上锁,写操作完成或者读操作完成以余扮野后就解锁,这种问题涉及线程间的通讯,只能够通过两个线程的交互来实现通讯,目缺乎前你看起来复杂,但是用得多了,也就不复杂了。线程1“通知”线程2,或者线程2“通知”线程1,其实要利用信号量机制,需要调用wait()与signal()函数,除此之外,还可以利用管程机制来实现线程之间的通讯,深入理解的话建议看看操作系统有关进程同步的教材。