1、1操作系统课后题挑选整理 GL1.4 在下面举出的三个功能中,哪个功能在下列两种环境下,(a)手持装置(b)实时系统需要操作系统的支持?(a)批处理程序(b)虚拟存储器(c)分时Answer:对于实时系统来说,操作系统需要以一种公平的方式支持虚拟存储器和分时系统。对于手持系统,操作系统需要提供虚拟存储器,但是不需要提供分时系统。批处理程序在两种环境中都是非必需的。1.10 中断(interupt)的目的是什么?陷阱(trap)与中断的区别是什么?陷阱可以被用户程序(user program)有意地的产生吗?如果可以,那目的是什么?Answer: 中断是一种在系统内硬件产生的流量变化。中断操作装
2、置是用来处理中断请求;然后返回控制中断的上下文和指令。陷阱是软件产生的中断。中断可以被用来标志 I/O 的完成,从而排除设备投票站(device polling)的需要。陷阱可以被用来调用操作系统的程序或者捕捉到算术错误。1.11 内存存储是被用于高速的 I/O 设备,其目的是为了避免增加 CPU 的过度运行。(a)设备的 CPU 接口是怎样与转换器(transfer)协作的?(b)当内存操作完全时,CPU 是怎么知道的?(c)当 DMA 控制器正在转换数据时,CPU 是被允许运行其它程序的。这种进程与用户程序的运行冲突吗?如果冲突的话,试描述可能引起哪种冲突?Answer: CPU 可以通过
3、写数据到可以被设备独立存储的寄存器中来启动 DMA 操作。当设备接收到来自 CPU 的命令时,启动响应的操作。当设备完成此操作时,就中断 CPU 来说明操作已经完成。设备和 CPU 都可以被内存同时访问。内存控制器对这两个实体以公平的方式给内存总线提供存取。CPU 可能不能同时以很快的速度配给给内存操作,因为它必须去竞争设备而使得自己存取到内存总线中去。1.12 一些计算机系统没有在硬件中提供个人模式(privileged mode) 。对于这种计算机系统来说,可能构成安全的操作系统吗?对可能和不可能两种情况分别给出理由。Answer:一种类型处理器的操作系统需要在任何时候都被控制(或监测模式
4、) 。有两种方法可以完成这个操作:a.所有用户程序的软件翻译(像一些BASIC,Java,LISP systems) 。在软件中,软件解释程序能够提供硬件所不能提供的。b.要求所有程序都用高级语言编写,以便于所以目标代码都被编译出来。编译器将会产生硬件忽略的防护性检查(in-line 或功能调用) 。1.15 试描述一个机器装置为了阻止一个程序避免修改与其它程序有联系的内存而执行内存保护。Answer:处理器可以追踪哪个位置是与每个进程相联系的以及限制进入一个程序的范围的外面位置。信息与一个程序的内存范围有关,它可以通过使用库,限制寄存器和对每个进入内存的信息执行检查来维持其本身。2.1 操作
5、系统提供的服务和功能可以分为两个类别。简单的描述一下这两个类别并讨论他们的不同点。Answer:第一种操作系统提供的服务是用来保护在系统中同时运行的不同进程。进程只被允许获得与它们地址空间有联系的内存位置。同样,进程不允许破坏和其他用户有关的文件。一个进程同样不允许在没有操作系统的干预下直接进2入设备。第二种服务由操作系统提供的服务是提供一种新的功能,而这种功能并不直接被底层的硬件支持。虚拟存储器和文件系统就是由操作系统提供的这种新服务的实例。2.2 列出操作系统提供的五项服务。说明每项服务如何给用户提供便利。说明在哪些情况下用户级程序不能够提够这些服务。Answer: a.文件执行.操作系统
6、一个文件的目录(或章节)装入到内存并运行。一个用户程序不能被信任,妥善分配 CPU 时间。b.I/O 操作. 磁盘,磁带,串行线,和其他装置必须在一个非常低的水平下进行通信。用户只需要指定装置和操作执行要求,然后该系统的要求转换成装置或控制器的具体命令.用户级程序不能被信任只在他们应该获得时获得装置和只使用那些未被使用的装置。c.文件系统操作.在文件创建、删除、分配和命名时有许多细节是用户不能执行的。磁盘空间块被文件所使用并被跟踪。删除一个文件需要清除这个文件的信息和释放被分派给这个文件的空间。用户程序不仅不能够保证保护方法的有效实施,也不能够被信任只会分配空闲的空间和在删除文件是清空空间。d
7、.通信.信息在系统间交换要求信息转换成信息包,送到网络控制器中,通过通信媒介进行传播,并由目的地系统重新组装。信息包调整和数据修改是一定会发生的。此外,用户程序也许不能够协调网络装置的取得,或者接收完全不同的其他进程的信息包。e.错误检测.错误检测在硬件和软件水平下都会发生。在硬件水平下,所有数据转移都必须仔细检查以确保数据在运送中不会被破坏。在媒介中的所有数据都必须被检查以确保他们在写入媒介时没有被改变。在软件水平下,为了数据,媒介不需不间断的被检查。例如,确保信息存储中被分配和还未被分配的空间块的数量和装置中所有块的数量的一致。进程独立经常有错误(例如,磁盘中数据的破坏) ,所以必须有一个
8、统筹的程序(操作系统)来处理各种错误。同样,错误经过操作系统的处理,在一个系统中程序不再需要包含匹配和改正所遇可能错误的代码。2.5 操作系统关于文件管理的五个主要活动是什么?Answer:1.创建和删除文件2.创建和删除目录3.提供操作文件和目录的原语的支持4.将文件映射到二级存储器上5.在稳定(非易失的)的存储媒介上备份文件。2.8 通信的两种模式是什么?这两种模式的优点和缺点是什么?Answer:通信的两种模式是 1)共享内存,2)消息传递。这两种模式的最基本的不同是在它们的性能上。一个内存共享块是通过系统调用创建的。然而,一旦内存共享块在两个或更多的进程间建立,这些进程可以借助内存共享
9、块来通信,不再需要内核的协助。另一方面,当 send()和 receive()操作被调用时,信息传递通常包含系统调用。因此,因为内核是直接的包含在进程间通信的,一般而言,它的影响比内存共享小。然而,消息传递可以用作同步机制来处理通信进程间的行动。也就是说,send()和 receive()段可以用来协调两个通信进程的动作。另一方面,内存共享没有提供这种同步机制的进程。2.12 采用微内核方法来设计系统的主要优点是什么?在微内核中如何使客户程序和系统服务相互作用?微内核方法的缺点是什么?3Answer:优点主要包括以下几点:a)增加一个新的服务不需要修改内核b) 在用户模式中比在内核模式中更安全
10、、更易操作c) 一个简单的内核设计和功能一般导致一个更可靠的操作系统用户程序和系统服务通过使用进程件的通信机制在微内核中相互作用,例如发送消息。这些消息由操作系统运送。微内核最主要的缺点是与进程间通信的过度联系和为了保证用户程序和系统服务相互作用而频繁使用操作系统的消息传递功能。2.13 模块化内核方法的什么方式与分层方法相似?什么方式与分层方法不同?Answer:模块化内核方法要求子系统通过创建的一般而言狭隘(从功能方面来说是揭露外部模块)的接口来相互作用。分层内核方法在细节上与分层方法相似。但是,分层内核必须要是有严格排序的子系统,这样的子系统在较低层次中不允许援引业务相应的上层子系统 。
11、在模块化内核方法中没有太多的限制,模式在哪方面是随意援引彼此的是没有任何约束的。3.1 论述短期,中期和长期调度之间的区别.Answer:a.短期调度:在内存作业中选择就绪执行的作业,并为他们分配 CPU。b.中期调度:作为一种中等程度的调度程序,尤其被用于分时系统,一个交换方案的实施,将部分运行程序移出内存,之后,从中断处继续执行。c.长期调度(作业调度程序):确定哪些作业调入内存以执行.它们主要的不同之处是它们的执行的频率。短期调度必须经常调用一个新进程,由于在系统中,长期调度处理移动的作业时,并不频繁被调用,可能在进程离开系统时才被唤起。3.2 描述一下内核在两个进程间进行上下文功换的动
12、作.Answer:总的来说,操作系统必须保存正在运行的进程的状态,恢复进程的状态。保存进程的状态主要包括 CPU 寄存器的值以及内存分配,上下文切换还必须执行一些确切体系结构的操作,包括刷新数据和指令缓存。(书中答案)进程关联是由进程的 PCB 来表示的,它包括 CPU 寄存器的值和内存管理信息等。当发生上下文切换时,内核会将旧进程的关联状态保存在其PCB 中,然后装入经调度要执行的新进程的已保存的关联状态。4.1 举两个多线程程序设计的例子来说明多线程不比单线程方案提高性能答:1)任何形式的顺序程序对线程来说都不是一个好的形式。例如一个计算个人报酬的程序。2)另外一个例子是一个“空壳”程序,
13、如 C-shell 和 korn shell。这种程序必须密切检测其本身的工作空间。如打开的文件、环境变量和当前工作目录。4.2 描述一下线程库采取行动进行用户级线程上下文切换的过程 答:用户线程之间的上下文切换和内核线程之间的相互转换是非常相似的。但它依赖于线程库和怎样把用户线程指给内核程序。一般来说,用户线程之间的上下文切换涉及到用一个用户程序的轻量级进程(LWP)和用另外一个线程来代替。这种行为通常涉及到寄存器的节约和释放。4.4 以下程序中的哪些组成部分在多线程程序中是被线程共享的?a.寄存值 b.堆内存 c.全局变量 d.栈内存答:一个线程程序的线程共享堆内存和全局变量,但每个线程都
14、有属于自己的一组寄存值和栈内存。5.1 为什么对调度来说,区分 I/0 限制的程序和 CPU 限制的程序是重要的?4答:I/0 限制的程序有在运行 I/O 操作前只运行很少数量的计算机操作的性质。这种程序一般来说不会使用很多的 CPU。另一方面,CPU 限制的程序利用整个的时间片,且不做任何阻碍 I/O 操作的工作。因此,通过给 I/O 限制的程序优先权和允许在 CPU 限制的程序之前运行,可以很好的利用计算机资源。5.2 讨论以下各对调度标准在某种背景下会有的冲突a.CPU 利用率和响应时间b.平均周转时间和最大等待时间c.I/O 设备利用率和 CPU 利用率答:a.CPU 利用率和响应时间
15、:当经常性的上下文切换减少到最低时,CPU 利用率增加。通过减少使用上下文切换程序来降低经常性的上下文切换。但这样可能会导致进程响应时间的增加。b.平均周转时间和最大等待时间:通过最先执行最短任务可以使平均周转时间最短。然而,这种调度策略可能会使长时间运行的任务永远得不到调度且会增加他们的等待时间。c.I/O 设备利用率和 CPU 利用率:CPU 利用率的最大化可以通过长时间运行 CPU限制的任务和同时不实行上下文切换。I/O 设备利用率的最大化可以通过尽可能调度已经准备好的 I/O 限制的任务。因此,导致上下文切换 。5.4 考虑下列进程集,进程占用的 CPU 区间长度以毫秒来计算:假设在时
16、刻 0 以进程 P1,P 2,P 3,P 4,P 5的顺序到达。a.画出 4 个 Gantt 图分别演示用 FCFS、SJF、非抢占优先级(数字小代表优先级高)和 RR(时间片 1)算法调度时进程的执行过程。b.在 a 里每个进程在每种调度算法下的周转时间是多少?c.在 a 里每个进程在每种调度算法下的等待时间是多少?d.在 a 里哪一种调度算法的平均等待时间对所有进程而言最小?答:a.甘特图略b.周转时间FCFS RR SJF 非抢占优先级P1 10 19 19 16P2 11 2 1 1P3 13 7 4 18P4 14 4 2 19P5 19 14 9 6c.等待时间FCFS RR SJ
17、F 非抢占优先级P1 0 9 9 6P2 10 1 0 0P3 11 5 2 16P4 13 3 1 18P5 14 9 4 2d.SJF进程 区间时间 优先级P1 10 3P2 1 1P3 2 3P4 1 4P5 5 255.5 下面哪些算法会引起饥饿a.先来先服务b.最短工作优先调度c.轮换法调度d.优先级调度答:最短工作优先调度和优先级调度算法会引起饥饿5.6 考虑 RR 调度算法的一个变种,在这个算法里,就绪队列里的项是指向 PCB的指针。a.如果把两个指针指向就绪队列中的同一个进程,会有什么效果?b.这个方案的主要优点和缺点是什么?c.如何修改基本的 RR 调度算法,从而不用两个指针
18、达到同样的效果?答.a.实际上,这个过程将会增加它的优先权,因为通过经常得到时间它能够优先得以运行。b.优点是越重要的工作可以得到更多的时间。也就是说,优先级越高越先运行。然而,结果将由短任务来承担。c.分配一个更长的时间给优先级越高的程序。换句话说,可能有两个或多个时间片在 RR 调度中。5.7 考虑一个运行十个 I/O 限制任务和一个 CPU 限制任务的系统。假设,I/O 限制任务一次分配给一个 I/O 操作 1 毫秒的 CPU 计算,但每个 I/O 操作的完成需要 10 毫秒。同时,假设间接的上下文切换要 0.1 毫秒,所有的进程都是长进程。对一个 RR 调度来说,以下情况时 CPU 的
19、利用率是多少:a.时间片是 1 毫秒b.时间片是 10 毫秒答:a.时间片是 1 毫秒:不论是哪个进程被调度,这个调度都会为每一次的上下文切换花费一个 0.1 毫秒的上下文切换。CPU 的利用率是 1/1.1*100=92%。b.时间片是 10 毫秒:这 I/O 限制任务会在使用完 1 毫秒时间片后进行一次上下文切换。这个时间片要求在所有的进程间都走一遍,因此,10*1.1+10.1(因为每个 I / O 限定任务执行为 1 毫秒,然后承担上下文切换的任务,而 CPU 限制任务的执行 10 毫秒在承担一个上下文切换之前) 。因此,CPU 的利用率是20、21.1*100=94%。5.9 考虑下
20、面的基于动态改变优先级的可抢占式优先权调度算法。大的优先权数代表高优先权。当一个进程在等待 CPU 时(在就绪队列中,但未执行) ,优先权以 速率改变;当它运行时,优先权以速率 改变。所有的进程在进入就绪队列时被给定优先权为 0。参数 和 可以设定给许多不同的调度算法。a.0 时所得的是什么算法?b.=1,那么 Pi 进程至少有一个资源可以释放。从而系统就不会进入死锁状态。8.3 按顺序给出 5 个部分的内存,分别是 100KB,500KB,200KB,300KB 和 600KB,用 first-fit,best-fit 和 worst-fit 算法,能够怎样按顺序分配进程212KB,417K
21、B,112KB,426KB 和 426KB?哪个算法充分利用了内存空间?Answer:a. First-fit:b. 212K is put in 500K partitionc. 417K is put in 600K partition7d. 112K is put in 288K partition (new partition 288K = 500K 212K)e. 426K must waitf. Best-fit:g. 212K is put in 300K partitionh. 417K is put in 500K partitioni. 112K is put in 200
22、K partitionj. 426K is put in 600K partitionk. Worst-fit:l. 212K is put in 600K partitionm. 417K is put in 500K partitionn. 112K is put in 388K partitiono. 426K must waitBest-fit: 算法充分利用了内存空间。8.4 在运行过程中,许多系统允许程序分配更多的内存给它的地址空间。在程序堆中的数据分配是这种分配方式的一个实例。在下面的方案中,为了支持动态内存分配的要求是什么?a.连续内存分配 b.纯段式分配 c.纯页式分配Ans
23、wer:a. 连续内存分配:当没有足够的空间给程序去扩大它已分配的内存空间时,将要求重新分配整个程序。b. 纯段式分配:当没有足够的空间给段去扩大它的已分配内存空间时,将要求重新分配整个段。c. 纯页式分配:在没有要求程序地址空间再分配的方案下,新页增加的分配是可能的。8.9 考虑一个分页系统在内存中存储着一张页表。a.如果内存的查询需要 200毫秒,那么一个分页内存的查询需要多长时间?b.如果我们加上相关联的寄存器,75%的页表查询可以在相关联的寄存器中找到,那么有效的查询时间是多少?(假设如果入口存在的话,在相关的寄存器中找到页表入口不花费时间)Answer:a.400 毫秒:200 毫秒
24、进入页表,200 毫秒进入内存中的字b.有效进入时间=0.75*200 毫秒+0.25*400 毫秒=250 毫秒8.129.4 某个计算机给它的用户提供了 232的虚拟内存空间,计算机有 214B 的物理内存,虚拟内存使用页面大小为 4094B 的分页机制实现。一个用户进程产生虚拟地址 11123456,现在说明一下系统怎么样建立相应的物理地址,区分一下软件操作和硬件操作。 (第六版有翻译)答:该虚拟地址的二进制形式是 0001 0001 0001 0010 0011 0100 0101 0110。由于页面大小为 212,页表大小为 220,因此,低 12 位的“0100 0101 0110
25、 ”被用来替换页( page) ,而前 20 位“0001 0001 0001 0010 0011”被用来替换页表(page table)。10.2 打开文件表被用以保持当前打开文件的信息,操作系统应该为每个用户保持一个单独的表吗?或者只是保持一个包含当前所有用户访问文件的引用的表?如果两个不同程序或用户访问同样的文件,在打开文件表中应包含单独的条目吗?Answer: 保持一个中央的打开文件表,操作系统可以执行下列操作,否则不可执行:假设一个当前有一个或一个以上进程访问的文件。如果该文件被删除,8那么应该直到所有正在访问文件的进程关闭它时,它才能从磁盘上删除。只要有正在访问文件的进程数目的集中
26、核算,该检查就可以执行。另一方面,如果两个进程正在访问该文件,则需要保持两个单独的状态来跟踪当前位置,其中部分文件正被两个进程访问。这就要求操作系统为两个进程保持单独的条目。10.9 有些系统文件提供文件共享时候只保留文件的一个拷贝,而另外的一个系统则是保留多个拷贝,对共享文件的每一个用户提供一个拷贝,论述这种方法的相对优点。答:在一个单一的复制,同时更新了一个文件可能会导致用户获得不正确的信息,文件被留在了不正确的状态. 随着多份拷贝,它会浪费存储而且各种副本可能不一致。11.2使用FAT链合作区块的档案来进行变化相联系的分配有哪些优势?答:它的优势是,在访问块是储存在中间的文件时候,在 F
27、AT 里跟踪指针可以决定它的位置,而不是访问所有个别区块中的档案顺序的方式找到指针的目标块。通常情况下,大多数的 FAT 可缓存在存储器里 ,因此,指针可以通过记忆体确定,而不用通过磁盘块。11.4有些档案系统允许磁盘存储将分配在不同级别的粒度。举例来说,一个文件系统可以分配4 KB的磁盘空间作为单一的一个4字节的块或8个512字节的块。我们如何能利用这种灵活性来提高性能?对自由空间管理做出哪些修改以支持这一功能?答:此项计划将减少内部分裂。如果文件是5字节,然后可以分配4 KB的区块和两个毗连的512字节的块。除了维持一个位图的自由块,一个目前正在使用的区块内也将保持额外的状态。当所有的分块
28、成为空闲时候,该分配器将不得不审查这笔额外分配状态分块和凝聚的分块,以获取更大的块。11.6 设想一个在磁盘上的文件系统的逻辑块和物理块的大小都为512B。假设每个文件的信息已经在内存中,对3种分配方法(连续分配,链接分配和索引分配),分别回答下面的问题:A,逻辑地址到物理地址的映射在系统中怎么样进行的?(对于索引分配,假设文件总是小于512块长)B,假设现在处在逻辑块10(最后访问的块是块10) ,限制想访问块4,那么必须从磁盘上读多少个物理块)答:设想Z是开始文件的地址(块数) ,a.毗连。分裂逻辑地址由512的X和Y所产生的份额和其余的分别。1:将X加入到Z获得物理块号码。 Y是进入该区
29、块的位移。2.:1b.联系。分裂逻辑地址由511的X和Y所产生的份额和其余的分别。1.:找出联系名单(将X + 1块) 。 Y + 1是到最后物理块的位移2.:4c.收录。分裂的逻辑地址由512的X和Y所产生的份额和其余的分别。1.:获得该指数块到内存中。物理块地址载于该指数在所在地块10, Y是到理想的物理块的位移。2.:212.2 假设一个错哦盘驱动器有 5000 个柱面,从 0 到 4999,驱动器正在为柱面 143 的一个请求提供服务,且前面的一个服务请求是在柱面 125.按 FIFO 顺序,即将到来的请求队列是986,1470,913,1774,948,1509,1022,1750,
30、130从现在磁头位置开始,按照下面的磁盘调度算法,要满足队列中即将到来的请求要求磁头总的移动距离(按柱面数计)是多少?a. FCFS; b. SSTF; c. SCAN; d. LOOK; e. C-SCAN答 a. FCFS 的调度是 143 , 86 , 1470 , 913 , 1774 , 948 , 1509 , 1022 , 1750 , 130 。总寻求距离是 7081 。b. SSTF 的调度是 143 , 130 , 86 , 913 , 948 , 1022, 1470, 1509, 1750, 1774。总寻求距离是 1745。 c. SCAN 的调度是 143 , 91
31、3 , 948 , 1022, 1470, 1509, 1750, 1774 , 4999 , 130 , 86 。总寻求距离是 9769 。d. LOOK 的调度是 143 , 913 , 948 , 1022, 1470, 1509, 1750, 1774, 130 , 86 。总寻求距离是 3319 。 e. C-SCAN 的调度是 143 , 913 , 948 , 1022 , 1470 , 1509 , 1750 , 1774 , 4999 , 86 , 130 。总寻求距离是 9813 。f. C-LOOK 的调度是 143 , 913 , 948 , 1022 , 1470 ,
32、 1509 , 1750 , 1774 , 86 , 130 。总寻求距离是 3363 。13.1; 13.3; 13.5 独木桥问题:过桥时,同一方向的行人可连续过桥,当某一方有人过桥时,另一方向的行人必须等待;当某一方向无人过桥时,另一方向的行人可以过桥。试用信号量机制解决。(1)需要设置几个信号量?分别是互斥信号量还是同步信号量?初值设为多少?并说明设置它们的意义。(2)写出用信号量机制解决此问题的算法。答案:(1) 将独木桥的两个方向分别标记为 A 和 B。用整型变量 countA 和 countB 分别表示 A、B方向上已在独木桥上的行人数。初值为 0。需要设置三个初值都为 1 的互
33、斥信号量:SA 用来实现对 countA 的互斥访问,SB 用来实现对 countB 的互斥访问,mutex 用来实现对独木桥的互斥使用。(2)A 方向行人过桥:BeginP(SA);countA=countA+1;if (countA= =1)P(mutex);V(SA);过桥;P(SA);countA=countA-1;if(countA= =0)V(mutex);V(SA);EndB 方向行人过桥:BeginP(SB);countB=countB+1;if (countB= =1)P(mutex);V(SB);过桥;P(SB);countB=countB-1;if(countB= =0)
34、V(mutex);V(SB);End10理发师问题:设有一个理发师,5 把椅子(另外还有一把理发椅),几把椅子可用连续存储单元。要求;(1) 每个顾客进入理发室后,即时显示“Entered” 及其线程标识,还同时显示理发室共有几名顾客及其所坐的位置。(2) 至少有 10 个顾客,每人理发至少 3 秒钟。(3) 多个顾客须共享操作函数代码。问题分析题目中要求描述理发师和顾客的行为,因此需要两类进程 Barber ()和 Customer()分别描述理发师和顾客的行为。当理发师看报时顾客近来需要唤醒理发师为其理发,当有顾客时理发师为其理发,没有的时候理发师看报,因此理发师和顾客之间是同步的关系,由
35、于每次理发师只能为一个人理发,且可供等侯的椅子有限只有 n 个,即理发师和椅子是临界资源,所以顾客之间是互斥的关系。故引入 3 个信号量和一个控制变量:1)控制变量waiting 用来记录等候理发的顾客数,初值均为 0;2)信号量 customers 用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为 0;3)信号量 barbers 用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为 0;4)信号量 mutex 用于互斥,初值为 1问题实现1.PV 操作代码如下:int waiting=0 ; /等候理发的顾客数 int chairs=n; /为顾客准备的椅子数 semaphore
36、 customers=0, barbers=0,mutex=1; barber()while(TRUE); /理完一人,还有顾客吗?P(cutomers); /若无顾客,理发师睡眠 P(mutex); /进程互斥 waiting := waiting 1; /等候顾客数少一个V(barbers); /理发师去为一个顾客理发V(mutex); /开放临界区cut-hair( ); /正在理发customer()P(mutex); /进程互斥if (waiting) waiting := waiting+1; / 等候顾客数加 1V(customers); /必要的话唤醒理发师V(mutex); /开放临界区P(barbers); /无理发师, 顾客坐着养神get-haircut( ); /一个顾客坐下等理/ elseV(mutex); /人满了,走吧!