【操作系统】操作系统大作业&相关知识整理

本文介绍了一种使用信号量解决银行柜员服务问题的方法。通过编程实现顾客取号与柜员叫号的过程,确保了顾客与柜员之间的同步操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

操作系统大作业&相关知识整理

我校的操作系统大作业为N选3,以下为三个较为简单的例子的实现
参考代码 见连接


1. 银行柜员服务问题

进程间同步/互斥问题
通过该实验熟悉信号量的处理及其在多线程程序中的应用

实验题目

题目描述:
 银行有n个柜员负责为顾客服务,顾客进入银行先取一个号码,>然后等着叫号。当某个柜员空闲下来,就叫下一个号。
编程实现该问题,用P、V操作实现柜员和顾客的同步。

实现要求:
  1. 某个号码只能由一名顾客取得;
  2. 不能有多于一个柜员叫同一个号;
  3. 有顾客的时候,柜员才叫号;
  4. 无柜员空闲的时候,顾客需要等待;
  5. 无顾客的时候,柜员需要等待。

实验环境:
 Windows10
 VS2015

设计思路&程序结构


题目要求顾客取号与柜台叫号通过互斥对象完成,故建立两个信号量分别作为取号与叫号的信号量。
此外,题目要求顾客与柜台间进行同步操作,为每个顾客分配一个信号量用于完成顾客与柜台间的同步。具体实现可参考项目代码,其中进行了详细的注释

题目整体完成过程如下:

  首先从输入文件读取各个顾客的信息
  而后创建时钟函数用于记录程序开始的时间(程序中时钟周期记录在T中)
  接下来依次创建柜台实例并为每个柜台开启一个线程,该线程进行忙等待直至有顾客等待(waitlist队列长度不为0),则叫号并开始服务。
  为每个柜台开启叫号线程后顾客开始进入,判定顾客进入的方法同样为忙等待,判定当前时间每个顾客是否应当进入,若到达其进入时间则为其开启一个取号线程。
  当所有顾客服务结束后输出最终结果。
  题目整体完成结构见main.cpp中的int main() 及 void start()
 

模拟时钟计时操作如下:

  定义了一个全局变量time用于记录当前时刻,clock线程不断循环睡眠Tms,每两次睡眠之间time自增一次,即完成了用time记录当前时刻的功能
  模拟时钟过程见main.cpp中的void clock()

模拟顾客取号操作过程如下:

  定义了全局变量M_GET_NUM为用户取号信号量,全局变量NUM为当前号码。此外定义了顾客等待队列waitlist用于记录当前在排队的顾客及其顺序。M_CUSTOM为顾客柜台同步信号量,用于保护服务过程中可能用到的资源,在用户实例初始化时进行P操作。当用户取号时,先对该信号量进行一次P操作,而后记录当前号码NUM为该顾客取得的号码,当前号码加一。将该顾客加入到排队的队列waitlist中。顾客取号操作完毕,对M_GET_NUM进行V操作
  顾客取号过程见main.cpp中的void Get_num(customer *this_customer)

模拟柜台叫号操作过程如下:

  定义了全局变量M_CALL_NUM为柜台叫号信号量,全局变量NUM_DONE为当前已完成服务的顾客数。当柜台叫号时,先对M_CALL_NUM进行P操作,而后判断当前等待队列waitlist是否为空,若不为空则直接对M_CALL_NUM进行V操作,继续进行忙等待,否则对当前等待队列waitlist中的队首取出,从队列中移除,叫号过程结束,对M_CALL_NUM进行V操作,而后对刚刚取出的其进行服务。开始服务时被服务的顾客记录当前时刻为开始服务时刻,当前柜台为服务柜台。服务过程通过Sleep函数模拟,服务结束后顾客记录当前时间为结束服务时间,并对M_CUSTOM进行V操作,即服务完成顾客用于服务的相应资源可继续用于其他用途。柜台在服务完成后继续开始叫号。
  柜台叫号过程见main.cpp中的void Call_num(server *this_server)


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值