[{"data":1,"prerenderedAt":1427},["ShallowReactive",2],{"note:cs\u002Fos\u002Freview\u002Fmidterm-exercise":3,"site-search-catalogue":1426},{"id":4,"title":5,"body":6,"description":731,"extension":1420,"meta":1421,"navigation":1255,"path":1422,"seo":1423,"stem":1424,"__hash__":1425},"notes\u002Fsource\u002Fcs\u002Fos\u002Freview\u002Fmidterm-exercise.md","Midterm Exercise",{"type":7,"value":8,"toc":1408},"minimark",[9,12,17,22,26,112,114,118,154,158,187,189,193,199,217,219,225,241,243,249,265,267,273,289,291,297,313,315,321,337,339,345,361,363,369,385,387,391,396,405,407,412,419,421,426,446,448,453,473,475,480,506,508,513,527,529,533,538,541,661,667,673,679,694,702,716,718,722,725,783,786,789,792,795,797,801,911,941,946,976,979,1181,1186,1194,1199,1404],[10,11],"hr",{},[13,14,16],"h2",{"id":15},"title-ch1ch6-期中复习习题order-1","title: CH1–CH6 期中复习习题\norder: 1",[18,19,21],"h1",{"id":20},"ch1ch6-期中复习习题","CH1–CH6 期中复习习题",[13,23,25],{"id":24},"basic-concepts","Basic Concepts",[27,28,29,40,48,56,64,72,80,88,96,104],"ol",{},[30,31,32,36,39],"li",{},[33,34,35],"strong",{},"Operating System（操作系统）",[37,38],"br",{},"\n首先是一个程序（系统程序），其功能是控制应用程序的执行；一个接口，连接应用程序和计算机硬件。",[30,41,42,45,47],{},[33,43,44],{},"Process（进程）",[37,46],{},"\n一个正在运行的程序；一个运行程序的实例；分配且能够在处理器上执行的实体；由一组执行的指令、一个当前状态和一组相关的系统资源表征的活动单元。",[30,49,50,53,55],{},[33,51,52],{},"Thread（线程）",[37,54],{},"\n操作系统中能够运算调度的最小单位。",[30,57,58,61,63],{},[33,59,60],{},"Concurrency（并发）",[37,62],{},"\n指在一个时间段内，操作系统中存在多个程序能够在同一个处理机上运行，但在任一个时刻点上只有一个程序在处理机上运行。",[30,65,66,69,71],{},[33,67,68],{},"Critical Section（临界区）",[37,70],{},"\n指一个访问临界资源的程序片段，临界资源指不可同时被多个进程或线程访问的共享资源。",[30,73,74,77,79],{},[33,75,76],{},"Mutual Exclusion（互斥）",[37,78],{},"\n进程之间因相互竞争共享资源所产生的一种制约关系，当一个进程进入临界区使用共享资源时，另一个进程必须等待。",[30,81,82,85,87],{},[33,83,84],{},"Synchronization（同步）",[37,86],{},"\n进程之间需要在执行的某个位置上协调工作次序、传递信息所产生的一种制约关系。",[30,89,90,93,95],{},[33,91,92],{},"Semaphore（信号量）",[37,94],{},"\n一个整数值，用于进程间信号的传递，作用于阻塞进程或解除阻塞。",[30,97,98,101,103],{},[33,99,100],{},"Deadlock（死锁）",[37,102],{},"\n一组相互竞争系统资源或进行通信的进程间的\"永久\"阻塞。",[30,105,106,109,111],{},[33,107,108],{},"Starvation（饥饿）",[37,110],{},"\n进程资源竞争而导致长时间得不到处理器时间的一种状态。",[10,113],{},[13,115,117],{"id":116},"fill-in-the-blanks","Fill in the Blanks",[27,119,120,130,133,136,139,142,145,148,151],{},[30,121,122,123,129],{},"The main objectives of the OS are: (",[124,125,126],"em",{},[33,127,128],{},") (",") and (___).",[30,131,132],{},"(___) was introduced in modern operating systems, making concurrency and sharing possible.",[30,134,135],{},"When a processor time slice of a process is exhausted, the process should change to the (___) state.",[30,137,138],{},"When creating a new process, the first step is to assign a unique (___) to the new process.",[30,140,141],{},"The first step in a full process switch is to save the (___) of the process.",[30,143,144],{},"In the instruction system, (___) can only be used by the Operating System.",[30,146,147],{},"(___) is a special integer variable to be used for signaling among processes.",[30,149,150],{},"(___) is a special semaphore that takes on only the values 0 and 1.",[30,152,153],{},"The operating system's (___) refers to its inherent flexibility in permitting functional modifications to the system without interfering with service.",[155,156,157],"p",{},"::: details Reference Answers",[27,159,160,163,166,169,172,175,178,181,184],{},[30,161,162],{},"Convenience（方便）、Efficiency（有效）、Ability to evolve（扩展能力）",[30,164,165],{},"Multiprogramming（多道程序设计）",[30,167,168],{},"Ready（就绪）",[30,170,171],{},"Identifier（标识符）",[30,173,174],{},"Context（上下文 \u002F 处理机状态字）",[30,176,177],{},"Privileged instructions（特权指令）",[30,179,180],{},"Semaphore \u002F Counting semaphore \u002F General semaphore（信号量）",[30,182,183],{},"Binary semaphore（二值信号量）",[30,185,186],{},"Ability to evolve（可扩展性）\n:::",[10,188],{},[13,190,192],{"id":191},"single-choice","Single Choice",[155,194,195,198],{},[33,196,197],{},"1."," A process is in (___) state when it is in the main memory and awaiting an event.",[200,201,202,205,208,214],"ul",{},[30,203,204],{},"A) Ready",[30,206,207],{},"B) Blocked\u002FSuspend",[30,209,210,213],{},[33,211,212],{},"C) Blocked"," (正确)",[30,215,216],{},"D) Ready\u002FSuspend",[10,218],{},[155,220,221,224],{},[33,222,223],{},"2."," Requested resources are granted to processes whenever possible with (___).",[200,226,227,232,235,238],{},[30,228,229,213],{},[33,230,231],{},"A) Deadlock detection",[30,233,234],{},"B) Deadlock avoidance",[30,236,237],{},"C) Mutual exclusion",[30,239,240],{},"D) Preemption",[10,242],{},[155,244,245,248],{},[33,246,247],{},"3."," In a three state Process Model, (___) is not a valid state transition.",[200,250,251,256,259,262],{},[30,252,253,213],{},[33,254,255],{},"A) Block -> Running",[30,257,258],{},"B) Running → Block",[30,260,261],{},"C) Ready → Running",[30,263,264],{},"D) Running → Ready",[10,266],{},[155,268,269,272],{},[33,270,271],{},"4."," The permanent blocking of a set of processes that either compete for system resources or communicate with each other is called: (___).",[200,274,275,278,283,286],{},[30,276,277],{},"A) Starvation",[30,279,280,213],{},[33,281,282],{},"B) Deadlock",[30,284,285],{},"C) Prioritization",[30,287,288],{},"D) Mutual exclusion",[10,290],{},[155,292,293,296],{},[33,294,295],{},"5."," Suppose the initial value of a semaphore associated with a resource is 4 and the current value is −2. If V is the number of available resources and W is the number of processes waiting for the resources, then V and W are (___) respectively.",[200,298,299,304,307,310],{},[30,300,301,213],{},[33,302,303],{},"A) 0, 2",[30,305,306],{},"B) 4, 0",[30,308,309],{},"C) 2, 0",[30,311,312],{},"D) −2, 0",[10,314],{},[155,316,317,320],{},[33,318,319],{},"6."," The end of a printout requested by a process will cause the process state to change from (___).",[200,322,323,326,329,332],{},[30,324,325],{},"A) running → ready",[30,327,328],{},"B) running → blocking",[30,330,331],{},"C) ready → running",[30,333,334,213],{},[33,335,336],{},"D) blocking -> ready",[10,338],{},[155,340,341,344],{},[33,342,343],{},"7."," If there are five plotters in the system and all processes need to use two of them. Suppose each process is allowed to request only one at a time, then at most (___) processes are allowed to compete without deadlock.",[200,346,347,350,353,356],{},[30,348,349],{},"A) 5",[30,351,352],{},"B) 2",[30,354,355],{},"C) 3",[30,357,358,213],{},[33,359,360],{},"D) 4",[10,362],{},[155,364,365,368],{},[33,366,367],{},"8."," In a concurrent system with multiple processes, there is certainly no deadlock due to contention over (___).",[200,370,371,374,377,380],{},[30,372,373],{},"A) Printer",[30,375,376],{},"B) Tape drive",[30,378,379],{},"C) CPU",[30,381,382,213],{},[33,383,384],{},"D) Disk",[10,386],{},[13,388,390],{"id":389},"questions","Questions",[155,392,393],{},[33,394,395],{},"1. What are the differences between process and thread?",[397,398,399],"blockquote",{},[155,400,401,404],{},[33,402,403],{},"答："," 进程是资源分配的基本单位；线程是处理器调度的基本单位。",[10,406],{},[155,408,409],{},[33,410,411],{},"2. Explain the relationship between program and process.",[397,413,414],{},[155,415,416,418],{},[33,417,403],{}," 程序是静态的，未装入内存中；而进程是动态的，是正在被执行的程序。一个程序可以对应多个进程，但一个进程只能对应一个程序。",[10,420],{},[155,422,423],{},[33,424,425],{},"3. What are the differences between reusable resources and consumable resources?",[397,427,428,432],{},[155,429,430],{},[33,431,403],{},[200,433,434,440],{},[30,435,436,439],{},[33,437,438],{},"可重用资源（Reusable Resource）","：一次仅供一个进程安全使用且不因使用而耗尽的资源。进程得到资源单元并使用后，会释放这些单元供其他进程再次使用。例如：处理器、I\u002FO 通道、内存和外存、设备，以及文件、数据库和信号量等数据结构。",[30,441,442,445],{},[33,443,444],{},"可消耗资源（Consumable Resource）","：可被创建（生产）和销毁（消耗）的资源。消费进程得到一个资源时，该资源就不再存在。例如：中断、信号、消息和 I\u002FO 缓冲区中的信息。",[10,447],{},[155,449,450],{},[33,451,452],{},"4. What are deadlock and livelock? Please briefly explain their difference.",[397,454,455,459],{},[155,456,457],{},[33,458,403],{},[200,460,461,467],{},[30,462,463,466],{},[33,464,465],{},"死锁（Deadlock）","：两个或两个以上的线程在执行过程中，由于竞争资源或彼此通信而造成的一种永久阻塞现象，若无外力作用，它们都将无法推进下去。",[30,468,469,472],{},[33,470,471],{},"活锁（Livelock）","：两个或两个以上的进程为响应其他进程中的变化而持续改变自己的状态，但不做有用工作的情况。进程没有被阻塞，但由于某些条件没有满足，导致一直重复\"尝试—失败—尝试—失败\"的过程。处于活锁的实体不断改变状态，活锁有可能自行解开。",[10,474],{},[155,476,477],{},[33,478,479],{},"5. List the requirements for mutual exclusion.",[397,481,482,486],{},[155,483,484],{},[33,485,403],{},[27,487,488,491,494,497,500,503],{},[30,489,490],{},"必须强制实施互斥：一次只允许一个进程进入临界区",[30,492,493],{},"一个在临界区停止的进程不能干涉其他进程",[30,495,496],{},"不能产生死锁或饥饿",[30,498,499],{},"在没有进程在临界区时，任何需要进入临界区的进程必须能够立即进入（公平性）",[30,501,502],{},"对进程的执行速度和处理器数量没有任何限制和要求",[30,504,505],{},"进程驻留在临界区的时间必须是有限的",[10,507],{},[155,509,510],{},[33,511,512],{},"6. List reasons why a mode switch between threads may be cheaper than a mode switch between processes.",[397,514,515,519],{},[155,516,517],{},[33,518,403],{},[200,520,521,524],{},[30,522,523],{},"线程共享内存和文件，线程切换不需要内核参与；",[30,525,526],{},"线程上下文切换所需开销比进程上下文切换开销小。",[10,528],{},[13,530,532],{"id":531},"problem-solving","Problem Solving",[534,535,537],"h3",{"id":536},"problem-1-银行家算法-bankers-algorithm","Problem 1 — 银行家算法 Banker's Algorithm",[155,539,540],{},"Suppose current system states are shown as in the following table, at this time Available = (1,2,1).",[542,543,544,545,544,582],"table",{},"\n  ",[546,547,548,549,548,565,544],"thead",{},"\n    ",[550,551,552,553,552,558,552,562,548],"tr",{},"\n      ",[554,555,557],"th",{"rowSpan":556},2,"Process",[554,559,561],{"colSpan":560},3,"Claim",[554,563,564],{"colSpan":560},"Allocation",[550,566,552,567,570,573,552,576,578,580,548],{},[554,568,569],{},"R1",[554,571,572],{},"R2",[554,574,575],{},"R3",[554,577,569],{},[554,579,572],{},[554,581,575],{},[583,584,548,585,548,607,548,626,548,644,544],"tbody",{},[550,586,587,591,594,597,599,602,605],{},[588,589,590],"td",{},"P1",[588,592,593],{},"3",[588,595,596],{},"2",[588,598,596],{},[588,600,601],{},"1",[588,603,604],{},"0",[588,606,604],{},[550,608,609,612,615,617,619,622,624],{},[588,610,611],{},"P2",[588,613,614],{},"6",[588,616,593],{},[588,618,601],{},[588,620,621],{},"5",[588,623,601],{},[588,625,601],{},[550,627,628,631,633,636,638,640,642],{},[588,629,630],{},"P3",[588,632,593],{},[588,634,635],{},"4",[588,637,601],{},[588,639,596],{},[588,641,601],{},[588,643,601],{},[550,645,646,649,651,653,655,657,659],{},[588,647,648],{},"P4",[588,650,635],{},[588,652,596],{},[588,654,596],{},[588,656,604],{},[588,658,596],{},[588,660,604],{},[155,662,663,666],{},[33,664,665],{},"(1)"," When P2 issues request₂(1,1,0), can the system allocate the resource? If yes, give a safety sequence.",[155,668,669,672],{},[33,670,671],{},"(2)"," After P2 issues request₂(1,1,0), P1 then issues request₁(0,1,0). Can the system allocate?",[155,674,675,678],{},[33,676,677],{},"(3)"," After P2 issues request₂(1,1,0), P3 then issues request₃(0,0,1). Can the system allocate?",[155,680,681,682,685,687,688,690,693],{},"::: details Reference Answers\n",[33,683,684],{},"(1) 可以分配。",[37,686],{},"\nP2 分配后仍可执行完毕，释放资源，不存在死锁情况。",[37,689],{},[33,691,692],{},"安全序列：P2 → P1 → P3 → P4","（P2 在最前即正确）",[155,695,696,699,701],{},[33,697,698],{},"(2) 不可以分配。",[37,700],{},"\nP2 和 P1 均分配后，剩余可用资源无法满足任何一个进程继续运行，会产生死锁。",[155,703,704,707,709,710,712,715],{},[33,705,706],{},"(3) 可以分配。",[37,708],{},"\nP2 仍能获得足够资源运行完毕，运行结束后释放资源，不会产生死锁。",[37,711],{},[33,713,714],{},"安全序列：P2 → P3 → P1 → P4","\n:::",[10,717],{},[534,719,721],{"id":720},"problem-2-信号量同步","Problem 2 — 信号量同步",[155,723,724],{},"两个进程并发执行，优先级相同，信号量 s1、s2 初值均为 0：",[726,727,732],"pre",{"className":728,"code":729,"language":730,"meta":731,"style":731},"language-c shiki shiki-themes github-light github-dark","P1() {                      P2() {\n  y = 1;                      x = 1;\n  y = y + 1;                  x = x + 3;\n  semSignal(s1);              semWait(s1);\n  z = y + 3;                  x = x + y;\n  semWait(s2);                semSignal(s2);\n  y = z + y;                  z = y + x;\n}                           }\n","c","",[733,734,735,743,748,753,759,765,771,777],"code",{"__ignoreMap":731},[736,737,740],"span",{"class":738,"line":739},"line",1,[736,741,742],{},"P1() {                      P2() {\n",[736,744,745],{"class":738,"line":556},[736,746,747],{},"  y = 1;                      x = 1;\n",[736,749,750],{"class":738,"line":560},[736,751,752],{},"  y = y + 1;                  x = x + 3;\n",[736,754,756],{"class":738,"line":755},4,[736,757,758],{},"  semSignal(s1);              semWait(s1);\n",[736,760,762],{"class":738,"line":761},5,[736,763,764],{},"  z = y + 3;                  x = x + y;\n",[736,766,768],{"class":738,"line":767},6,[736,769,770],{},"  semWait(s2);                semSignal(s2);\n",[736,772,774],{"class":738,"line":773},7,[736,775,776],{},"  y = z + y;                  z = y + x;\n",[736,778,780],{"class":738,"line":779},8,[736,781,782],{},"}                           }\n",[155,784,785],{},"请给出并发执行后 x、y、z 的值。",[155,787,788],{},"::: details Reference Answers\ny=2;x=4",[155,790,791],{},"Z=5;x=6",[155,793,794],{},"z=8;y=10;x=6  或者  y=7;z=13;x=6\n:::",[10,796],{},[534,798,800],{"id":799},"problem-3-生产者消费者问题","Problem 3 — 生产者消费者问题",[155,802,803,804,850,851,910],{},"三个工人 A、B、C 共享一个大小为 ",[736,805,808,830],{"className":806},[807],"katex",[736,809,812],{"className":810},[811],"katex-mathml",[813,814,816],"math",{"xmlns":815},"http:\u002F\u002Fwww.w3.org\u002F1998\u002FMath\u002FMathML",[817,818,819,826],"semantics",{},[820,821,822],"mrow",{},[823,824,825],"mi",{},"M",[827,828,825],"annotation",{"encoding":829},"application\u002Fx-tex",[736,831,835],{"className":832,"ariaHidden":834},[833],"katex-html","true",[736,836,839,844],{"className":837},[838],"base",[736,840],{"className":841,"style":843},[842],"strut","height:0.6833em;",[736,845,825],{"className":846,"style":849},[847,848],"mord","mathnormal","margin-right:0.109em;","（",[736,852,854,875],{"className":853},[807],[736,855,857],{"className":856},[811],[813,858,859],{"xmlns":815},[817,860,861,872],{},[820,862,863,865,869],{},[823,864,825],{},[866,867,868],"mo",{},"≥",[870,871,593],"mn",{},[827,873,874],{"encoding":829},"M \\geq 3",[736,876,878,900],{"className":877,"ariaHidden":834},[833],[736,879,881,885,888,893,897],{"className":880},[838],[736,882],{"className":883,"style":884},[842],"height:0.8193em;vertical-align:-0.136em;",[736,886,825],{"className":887,"style":849},[847,848],[736,889],{"className":890,"style":892},[891],"mspace","margin-right:0.2778em;",[736,894,868],{"className":895},[896],"mrel",[736,898],{"className":899,"style":892},[891],[736,901,903,907],{"className":902},[838],[736,904],{"className":905,"style":906},[842],"height:0.6444em;",[736,908,593],{"className":909},[847],"）的箱子：",[200,912,913,923,931],{},[30,914,915,918,919,922],{},[33,916,917],{},"Worker A","：持续生产 ",[33,920,921],{},"车架（frame）"," 并放入箱子",[30,924,925,918,928,922],{},[33,926,927],{},"Worker B",[33,929,930],{},"车轮（wheel）",[30,932,933,936,937,940],{},[33,934,935],{},"Worker C","：每次取 ",[33,938,939],{},"1 个车架 + 2 个车轮","，组装成自行车",[155,942,943],{},[33,944,945],{},"原始伪代码（未同步）：",[726,947,949],{"className":728,"code":948,"language":730,"meta":731,"style":731},"Worker A { while(true) { produce a frame;  put frame into box; } }\nWorker B { while(true) { produce a wheel;  put wheel into box; } }\nWorker C { while(true) { take a frame from box;\n                          take two wheels from box;\n                          assemble a bike; } }\n",[733,950,951,956,961,966,971],{"__ignoreMap":731},[736,952,953],{"class":738,"line":739},[736,954,955],{},"Worker A { while(true) { produce a frame;  put frame into box; } }\n",[736,957,958],{"class":738,"line":556},[736,959,960],{},"Worker B { while(true) { produce a wheel;  put wheel into box; } }\n",[736,962,963],{"class":738,"line":560},[736,964,965],{},"Worker C { while(true) { take a frame from box;\n",[736,967,968],{"class":738,"line":755},[736,969,970],{},"                          take two wheels from box;\n",[736,972,973],{"class":738,"line":761},[736,974,975],{},"                          assemble a bike; } }\n",[155,977,978],{},"Please use semWait and semSignal operation to achieve the cooperation of three workers respectively, which requires that the solution does not contain deadlock.",[155,980,981,984,986,987,1015,1016,1071,1072,1074,1075,1180],{},[33,982,983],{},"死锁分析：",[37,985],{},"\n若箱中 ",[736,988,990,1003],{"className":989},[807],[736,991,993],{"className":992},[811],[813,994,995],{"xmlns":815},[817,996,997,1001],{},[820,998,999],{},[823,1000,825],{},[827,1002,825],{"encoding":829},[736,1004,1006],{"className":1005,"ariaHidden":834},[833],[736,1007,1009,1012],{"className":1008},[838],[736,1010],{"className":1011,"style":843},[842],[736,1013,825],{"className":1014,"style":849},[847,848]," 个槽全部为车轮，或 ",[736,1017,1019,1038],{"className":1018},[807],[736,1020,1022],{"className":1021},[811],[813,1023,1024],{"xmlns":815},[817,1025,1026,1035],{},[820,1027,1028,1030,1033],{},[823,1029,825],{},[866,1031,1032],{},"−",[870,1034,601],{},[827,1036,1037],{"encoding":829},"M-1",[736,1039,1041,1062],{"className":1040,"ariaHidden":834},[833],[736,1042,1044,1048,1051,1055,1059],{"className":1043},[838],[736,1045],{"className":1046,"style":1047},[842],"height:0.7667em;vertical-align:-0.0833em;",[736,1049,825],{"className":1050,"style":849},[847,848],[736,1052],{"className":1053,"style":1054},[891],"margin-right:0.2222em;",[736,1056,1032],{"className":1057},[1058],"mbin",[736,1060],{"className":1061,"style":1054},[891],[736,1063,1065,1068],{"className":1064},[838],[736,1066],{"className":1067,"style":906},[842],[736,1069,601],{"className":1070},[847]," 个槽全为车架（剩余空间不足放第 2 个车轮），Worker C 均无法组装。",[37,1073],{},"\n因此：",[33,1076,1077,1078,1129,1130],{},"车架上限 = ",[736,1079,1081,1099],{"className":1080},[807],[736,1082,1084],{"className":1083},[811],[813,1085,1086],{"xmlns":815},[817,1087,1088,1096],{},[820,1089,1090,1092,1094],{},[823,1091,825],{},[866,1093,1032],{},[870,1095,596],{},[827,1097,1098],{"encoding":829},"M-2",[736,1100,1102,1120],{"className":1101,"ariaHidden":834},[833],[736,1103,1105,1108,1111,1114,1117],{"className":1104},[838],[736,1106],{"className":1107,"style":1047},[842],[736,1109,825],{"className":1110,"style":849},[847,848],[736,1112],{"className":1113,"style":1054},[891],[736,1115,1032],{"className":1116},[1058],[736,1118],{"className":1119,"style":1054},[891],[736,1121,1123,1126],{"className":1122},[838],[736,1124],{"className":1125,"style":906},[842],[736,1127,596],{"className":1128},[847],"，车轮上限 = ",[736,1131,1133,1150],{"className":1132},[807],[736,1134,1136],{"className":1135},[811],[813,1137,1138],{"xmlns":815},[817,1139,1140,1148],{},[820,1141,1142,1144,1146],{},[823,1143,825],{},[866,1145,1032],{},[870,1147,601],{},[827,1149,1037],{"encoding":829},[736,1151,1153,1171],{"className":1152,"ariaHidden":834},[833],[736,1154,1156,1159,1162,1165,1168],{"className":1155},[838],[736,1157],{"className":1158,"style":1047},[842],[736,1160,825],{"className":1161,"style":849},[847,848],[736,1163],{"className":1164,"style":1054},[891],[736,1166,1032],{"className":1167},[1058],[736,1169],{"className":1170,"style":1054},[891],[736,1172,1174,1177],{"className":1173},[838],[736,1175],{"className":1176,"style":906},[842],[736,1178,601],{"className":1179},[847],"。",[155,1182,1183],{},[33,1184,1185],{},"信号量定义：",[726,1187,1192],{"className":1188,"code":1190,"language":1191},[1189],"language-text","semaphore empty    = M      \u002F\u002F 空槽数量\nsemaphore frame    = 0      \u002F\u002F 箱中车架数\nsemaphore wheel    = 0      \u002F\u002F 箱中车轮数\nsemaphore maxframe = M - 2  \u002F\u002F 车架数上限\nsemaphore maxwheel = M - 1  \u002F\u002F 车轮数上限\n","text",[733,1193,1190],{"__ignoreMap":731},[155,1195,1196],{},[33,1197,1198],{},"完整同步伪代码：",[726,1200,1202],{"className":728,"code":1201,"language":730,"meta":731,"style":731},"Worker A {\n    while (true) {\n        produce a frame;\n        semWait(maxframe);   \u002F\u002F 车架未超上限\n        semWait(empty);      \u002F\u002F 有空槽\n        put frame into box;\n        semSignal(frame);    \u002F\u002F 车架数 +1\n    }\n}\n\nWorker B {\n    while (true) {\n        produce a wheel;\n        semWait(maxwheel);   \u002F\u002F 车轮未超上限\n        semWait(empty);      \u002F\u002F 有空槽\n        put wheel into box;\n        semSignal(wheel);    \u002F\u002F 车轮数 +1\n    }\n}\n\nWorker C {\n    while (true) {\n        semWait(frame);      \u002F\u002F 等待至少 1 个车架\n        take a frame from box;\n        semWait(wheel);      \u002F\u002F 等待至少 2 个车轮\n        semWait(wheel);\n        take two wheels from box;\n        assemble a bike;\n        semSignal(maxframe); \u002F\u002F 车架槽释放\n        semSignal(maxwheel); \u002F\u002F 车轮槽释放 ×2\n        semSignal(maxwheel);\n        semSignal(empty);    \u002F\u002F 空槽 +3\n        semSignal(empty);\n        semSignal(empty);\n    }\n}\n",[733,1203,1204,1209,1214,1219,1224,1229,1234,1239,1244,1250,1257,1263,1268,1274,1280,1285,1291,1297,1302,1307,1312,1318,1323,1329,1335,1341,1347,1353,1359,1365,1371,1377,1383,1389,1394,1399],{"__ignoreMap":731},[736,1205,1206],{"class":738,"line":739},[736,1207,1208],{},"Worker A {\n",[736,1210,1211],{"class":738,"line":556},[736,1212,1213],{},"    while (true) {\n",[736,1215,1216],{"class":738,"line":560},[736,1217,1218],{},"        produce a frame;\n",[736,1220,1221],{"class":738,"line":755},[736,1222,1223],{},"        semWait(maxframe);   \u002F\u002F 车架未超上限\n",[736,1225,1226],{"class":738,"line":761},[736,1227,1228],{},"        semWait(empty);      \u002F\u002F 有空槽\n",[736,1230,1231],{"class":738,"line":767},[736,1232,1233],{},"        put frame into box;\n",[736,1235,1236],{"class":738,"line":773},[736,1237,1238],{},"        semSignal(frame);    \u002F\u002F 车架数 +1\n",[736,1240,1241],{"class":738,"line":779},[736,1242,1243],{},"    }\n",[736,1245,1247],{"class":738,"line":1246},9,[736,1248,1249],{},"}\n",[736,1251,1253],{"class":738,"line":1252},10,[736,1254,1256],{"emptyLinePlaceholder":1255},true,"\n",[736,1258,1260],{"class":738,"line":1259},11,[736,1261,1262],{},"Worker B {\n",[736,1264,1266],{"class":738,"line":1265},12,[736,1267,1213],{},[736,1269,1271],{"class":738,"line":1270},13,[736,1272,1273],{},"        produce a wheel;\n",[736,1275,1277],{"class":738,"line":1276},14,[736,1278,1279],{},"        semWait(maxwheel);   \u002F\u002F 车轮未超上限\n",[736,1281,1283],{"class":738,"line":1282},15,[736,1284,1228],{},[736,1286,1288],{"class":738,"line":1287},16,[736,1289,1290],{},"        put wheel into box;\n",[736,1292,1294],{"class":738,"line":1293},17,[736,1295,1296],{},"        semSignal(wheel);    \u002F\u002F 车轮数 +1\n",[736,1298,1300],{"class":738,"line":1299},18,[736,1301,1243],{},[736,1303,1305],{"class":738,"line":1304},19,[736,1306,1249],{},[736,1308,1310],{"class":738,"line":1309},20,[736,1311,1256],{"emptyLinePlaceholder":1255},[736,1313,1315],{"class":738,"line":1314},21,[736,1316,1317],{},"Worker C {\n",[736,1319,1321],{"class":738,"line":1320},22,[736,1322,1213],{},[736,1324,1326],{"class":738,"line":1325},23,[736,1327,1328],{},"        semWait(frame);      \u002F\u002F 等待至少 1 个车架\n",[736,1330,1332],{"class":738,"line":1331},24,[736,1333,1334],{},"        take a frame from box;\n",[736,1336,1338],{"class":738,"line":1337},25,[736,1339,1340],{},"        semWait(wheel);      \u002F\u002F 等待至少 2 个车轮\n",[736,1342,1344],{"class":738,"line":1343},26,[736,1345,1346],{},"        semWait(wheel);\n",[736,1348,1350],{"class":738,"line":1349},27,[736,1351,1352],{},"        take two wheels from box;\n",[736,1354,1356],{"class":738,"line":1355},28,[736,1357,1358],{},"        assemble a bike;\n",[736,1360,1362],{"class":738,"line":1361},29,[736,1363,1364],{},"        semSignal(maxframe); \u002F\u002F 车架槽释放\n",[736,1366,1368],{"class":738,"line":1367},30,[736,1369,1370],{},"        semSignal(maxwheel); \u002F\u002F 车轮槽释放 ×2\n",[736,1372,1374],{"class":738,"line":1373},31,[736,1375,1376],{},"        semSignal(maxwheel);\n",[736,1378,1380],{"class":738,"line":1379},32,[736,1381,1382],{},"        semSignal(empty);    \u002F\u002F 空槽 +3\n",[736,1384,1386],{"class":738,"line":1385},33,[736,1387,1388],{},"        semSignal(empty);\n",[736,1390,1392],{"class":738,"line":1391},34,[736,1393,1388],{},[736,1395,1397],{"class":738,"line":1396},35,[736,1398,1243],{},[736,1400,1402],{"class":738,"line":1401},36,[736,1403,1249],{},[1405,1406,1407],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":731,"searchDepth":556,"depth":556,"links":1409},[1410,1411,1412,1413,1414,1415],{"id":15,"depth":556,"text":16},{"id":24,"depth":556,"text":25},{"id":116,"depth":556,"text":117},{"id":191,"depth":556,"text":192},{"id":389,"depth":556,"text":390},{"id":531,"depth":556,"text":532,"children":1416},[1417,1418,1419],{"id":536,"depth":560,"text":537},{"id":720,"depth":560,"text":721},{"id":799,"depth":560,"text":800},"md",{},"\u002Fsource\u002Fcs\u002Fos\u002Freview\u002Fmidterm-exercise",{"description":731},"source\u002Fcs\u002Fos\u002Freview\u002Fmidterm-exercise","WkikqUCl_MIqRPCWnGEhvRkaI3iWr7bBk88w5S2980c",null,1784032892109]