2023年全國(guó)碩士研究生考試考研英語(yǔ)一試題真題(含答案詳解+作文范文)_第1頁(yè)
已閱讀1頁(yè),還剩49頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、<p>  操作系統(tǒng)課程設(shè)計(jì)報(bào)告</p><p><b>  目錄</b></p><p><b>  目錄2</b></p><p><b>  一、 前期工作3</b></p><p><b>  1.1平臺(tái)搭建3</b></p&

2、gt;<p><b>  二、 代碼分工3</b></p><p><b>  三、設(shè)計(jì)及實(shí)現(xiàn)4</b></p><p>  3.1 Task1.1 KThread.join()4</p><p>  3.1.1 要求分析4</p><p>  3.1.2 設(shè)計(jì)方案4<

3、/p><p>  3.1.3 實(shí)現(xiàn)代碼4</p><p>  3.1.4 測(cè)試代碼及結(jié)果5</p><p>  3.2 Task1.2 condition2類(lèi)7</p><p>  3.2.1 要求分析7</p><p>  3.2.2 設(shè)計(jì)方案8</p><p>  3.2.3 實(shí)現(xiàn)代碼

4、8</p><p>  3.2.4 測(cè)試代碼及結(jié)果8</p><p>  3.3 Task1.3 alram類(lèi)11</p><p>  3.3.1 要求分析11</p><p>  3.3.2 設(shè)計(jì)方案11</p><p>  3.3.3 實(shí)現(xiàn)代碼12</p><p>  3.3.4

5、 測(cè)試代碼及結(jié)果12</p><p>  3.4 Task1.4 communicator類(lèi)14</p><p>  3.4.1要求分析14</p><p>  3.4.2 設(shè)計(jì)方案14</p><p>  3.4.3 實(shí)現(xiàn)代碼14</p><p>  3.4.4 測(cè)試代碼及結(jié)果15</p>

6、<p>  3.5 Task1.5 priority scheduler類(lèi)17</p><p>  3.5.1 要求分析17</p><p>  3.5.2 設(shè)計(jì)方案17</p><p>  3.5.3 實(shí)現(xiàn)代碼18</p><p>  3.5.4 測(cè)試代碼及結(jié)果18</p><p>  3.6 T

7、ask1.6 boat類(lèi)23</p><p>  3.6.1 要求分析23</p><p>  3.6.2 設(shè)計(jì)方案23</p><p>  3.6.3 實(shí)現(xiàn)代碼23</p><p>  3.6.4 測(cè)試代碼及結(jié)果30</p><p>  3.7 Task2.1 系統(tǒng)調(diào)用creat, open, read,

8、write, close, unlink30</p><p>  3.7.1 要求分析30</p><p>  3.7.2 設(shè)計(jì)方案31</p><p>  3.7.3 實(shí)現(xiàn)代碼32</p><p>  3.7.4 測(cè)試代碼及結(jié)果34</p><p>  3.8 Task2.2 多進(jìn)程內(nèi)存分配及訪問(wèn)35&l

9、t;/p><p>  3.8.1 要求分析35</p><p>  3.8.2 設(shè)計(jì)方案35</p><p>  3.8.3 實(shí)現(xiàn)代碼36</p><p>  3.8.4 測(cè)試代碼及結(jié)果39</p><p>  3.9 Task2.3 系統(tǒng)調(diào)用exec, join, exit41</p><p

10、>  3.9.1 要求分析41</p><p>  3.9.2 設(shè)計(jì)方案41</p><p>  3.9.3 實(shí)現(xiàn)代碼42</p><p>  3.9.4 測(cè)試代碼及結(jié)果43</p><p>  3.10 Task2.4 Lottery Schedule類(lèi)44</p><p>  3.10.1 要求分析

11、44</p><p>  3.10.2 設(shè)計(jì)方案45</p><p>  3.10.3 實(shí)現(xiàn)代碼45</p><p>  3.10.4 測(cè)試代碼及結(jié)果45</p><p><b>  總結(jié)48</b></p><p><b>  前期工作</b></p>

12、<p><b>  1.1平臺(tái)搭建</b></p><p>  Nachos For Java</p><p>  phrase1部分:IDE環(huán)境可采用Eclipse。</p><p>  Phase 2及以后階段:需要把C程序編譯成MIPS二進(jìn)制文件COFF,需要MIPS的C編譯器 mips-x86.linux-xgcc(ub

13、untu12.04平臺(tái)下)。</p><p><b>  代碼分工</b></p><p><b>  三、設(shè)計(jì)及實(shí)現(xiàn)</b></p><p>  3.1 Task1.1 KThread.join()</p><p>  3.1.1 要求分析</p><p>  Join()

14、方法的含義:當(dāng)前線程a在運(yùn)行,執(zhí)行b.join(),則a阻塞,直到線程b結(jié)束,a繼續(xù)執(zhí)行。</p><p>  Join函數(shù)的作用即為等待某線程運(yùn)行完畢。當(dāng)前線程 (唯一一個(gè)正在運(yùn)行的線程) A調(diào)用另一個(gè)線程 (處于就緒狀態(tài)) B的join函數(shù)時(shí) (A 和 B 在Nachos中均為KThread類(lèi)型對(duì)象),A被掛起,直到B運(yùn)行結(jié)束后, join函數(shù)返回,A才能繼續(xù)運(yùn)行。注意在一個(gè)KThread對(duì)象上只能調(diào)用一次j

15、oin,且當(dāng)前線程不能對(duì)自身調(diào)用join。</p><p>  3.1.2 設(shè)計(jì)方案</p><p>  為每個(gè)線程創(chuàng)建一個(gè)線程隊(duì)列joinqueue,joinqueue由對(duì)本線程調(diào)用join方法的其他線程對(duì)象構(gòu)成,可“捐贈(zèng)”優(yōu)先級(jí) ,以及布爾形變量joined,判斷本線程是否被其他線程調(diào)用過(guò)join方法,以及一個(gè)判斷線程狀態(tài)方法IsAlive()。</p><p>

16、;  假設(shè)當(dāng)前線程A調(diào)用就緒線程B的join函數(shù). 在join函數(shù)中線程A被添加到線程B的線程隊(duì)列joinqueue中,將線程A“休眠”, 線程B得到執(zhí)行,在線程B結(jié)束時(shí)(此時(shí)線程B成為當(dāng)前線程, 發(fā)生在KThead.finish函數(shù)中) 選擇B的joinqueue的nextThread()執(zhí)行, A喚醒并繼續(xù). </p><p>  3.1.3 實(shí)現(xiàn)代碼</p><p>  在KThre

17、ad.java 中: </p><p>  private ThreadQueue joinQueue = null; </p><p>  private boolean Joined = false;</p><p>  public boolean IsAlive(){</p><p>  if(this.status==sta

18、tusNew||status==statusReady||</p><p>  status==statusRunning||status==statusBlocked)</p><p>  return true;</p><p>  else return false;</p><p><b>  }</b><

19、/p><p>  public void join() {</p><p><b>  //</b></p><p>  if (!this.IsAlive()) return;</p><p>  while (IsAlive()) {</p><p><b>  //</b>

20、;</p><p>  this.joinQueue.acquire(this);</p><p><b>  //</b></p><p><b>  }</b></p><p>  this.joinQueue.waitForAccess(KThread.currentThread());<

21、;/p><p>  KThread.sleep();</p><p><b>  //</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  public static void finish() {&l

22、t;/p><p><b>  ///</b></p><p>  if (currentThread.Joined) {</p><p>  currentThread.joinQueue.nextThread().ready();</p><p><b>  }</b></p><

23、;p><b>  ///</b></p><p><b>  }</b></p><p>  3.1.4 測(cè)試代碼及結(jié)果</p><p>  創(chuàng)建AThread和Bthread兩個(gè)線程,AThread循環(huán)打印“AThread循環(huán)第..次”語(yǔ)句,Bthread開(kāi)始打印“B_thread 就緒”語(yǔ)句,中間執(zhí)行AThrea

24、d。Join()方法,最后打印“B_thread執(zhí)行結(jié)束”語(yǔ)句。</p><p><b>  測(cè)試代碼:</b></p><p>  package nachos.threads;</p><p>  import nachos.machine.*;</p><p>  public class KThreadTest

25、{</p><p>  public KThreadTest() {</p><p><b>  }</b></p><p>  public static void simpleJoinTest() {</p><p>  KThread A_thread = new KThread(new KThreadTest.A

26、_thread(5));</p><p>  KThread B_thread = new KThread(new KThreadTest.B_thread(A_thread));</p><p>  B_thread.fork();</p><p>  B_thread.join();</p><p><b>  }</b&

27、gt;</p><p>  public static class B_thread implements Runnable {</p><p>  B_thread(KThread joinee) {</p><p>  this.joinee = joinee;</p><p><b>  }</b></p&g

28、t;<p>  public void run() {</p><p>  System.out.println("B_thread 就緒");</p><p>  System.out.println("Forking and joining A_thread...");</p><p>  this.join

29、ee.fork();</p><p>  this.joinee.join();</p><p>  System.out.println("B_thread 執(zhí)行結(jié)束");</p><p><b>  }</b></p><p>  private KThread joinee;</p>

30、<p><b>  }</b></p><p>  public static class A_thread implements Runnable {</p><p>  A_thread(int num) {</p><p>  this.num = num;</p><p><b>  }&

31、lt;/b></p><p>  public void run() {</p><p>  System.out.println("A_thread 就緒");</p><p>  System.out.println("A_thread開(kāi)始執(zhí)行");</p><p>  // This sho

32、uld just kill some cycles</p><p>  for (int i = 0; i < this.num; ++i) {</p><p>  System.out.println("A_thread 循環(huán) 第" + i + " 次");</p><p>  KThread.currentThrea

33、d().yield();</p><p><b>  }</b></p><p>  System.out.println("A_thread 執(zhí)行結(jié)束");</p><p><b>  }</b></p><p>  private int num;</p>&l

34、t;p><b>  }</b></p><p><b>  }</b></p><p><b>  測(cè)試結(jié)果:</b></p><p>  3.2 Task1.2 condition2類(lèi)</p><p>  3.2.1 要求分析</p><p> 

35、 threads.Lock類(lèi)提供了鎖以保證互斥. 在臨界代碼區(qū)的兩端執(zhí)行Lock.acquire() 和Lock.release() 即可保證同時(shí)只有一個(gè)線程訪問(wèn)臨界代碼區(qū). 條件變量建立在鎖之上, 由threads.Condition實(shí)現(xiàn), 它是用來(lái)保證同步的工具. 每一個(gè)條件變量擁有一個(gè)鎖變量 (該鎖變量亦可被執(zhí)行acquire和release操作, 多個(gè)條件變量可共享同一個(gè)鎖變量). 當(dāng)處于臨界區(qū)內(nèi)的擁有某鎖Lock的當(dāng)前線程對(duì)與

36、鎖Lock聯(lián)系的條件變量執(zhí)行sleep操作時(shí), 該線程失去鎖L并被掛起. 下一個(gè)等待鎖L的線程獲得鎖L (這個(gè)過(guò)程由調(diào)度程序完成) 并進(jìn)入臨界區(qū). 當(dāng)擁有鎖L的臨界區(qū)內(nèi)的當(dāng)前線程對(duì)與鎖L聯(lián)系的條件變量執(zhí)行wake操作時(shí) (通常調(diào)用wake之后緊接著就是Lock.release), 等待在該條件變量上的至多一個(gè)被掛起的線程 (由調(diào)用sleep引起) 被重新喚醒并設(shè)置為就緒狀態(tài). 若執(zhí)行wakeall操作, 則等待在該條件變量上的所有被掛起

37、的線程都被喚醒. threads.condition已經(jīng)實(shí)現(xiàn)了一個(gè)條件變量 (采用信號(hào)量實(shí)現(xiàn)), 題目要求用屏蔽/禁止中斷</p><p>  3.2.2 設(shè)計(jì)方案</p><p>  為每個(gè)條件變量添加一個(gè)鎖conditionLock和一個(gè)Kthread對(duì)象組成的等待隊(duì)列waitqueue,condition.sleep 將調(diào)用sleep()的線程加入到等待隊(duì)列,釋放鎖,并阻塞,以便其他

38、線程喚醒它,一旦’喚醒’立即要求鎖,并在sleep函數(shù)開(kāi)始/結(jié)尾處屏蔽/允許中斷以保證原子性;condition.wake中從等待隊(duì)列中取出線程進(jìn)行ready()實(shí)現(xiàn)喚醒, </p><p>  (同樣要在wake函數(shù)開(kāi)始/結(jié)尾處屏蔽/允許中斷), wakeall函數(shù)的實(shí)現(xiàn)依賴(lài)于wake. 只需不斷地wake 直到隊(duì)列為空為止. </p><p>  3.2.3 實(shí)現(xiàn)代碼</p&g

39、t;<p>  見(jiàn)threads/condition2.java </p><p>  private Lock conditionLock;</p><p>  private LinkedList<KThread> waitQueue;</p><p>  public void sleep() {</p><p&g

40、t;<b>  //</b></p><p>  waitQueue.add(KThread.currentThread());</p><p>  conditionLock.release();</p><p>  KThread.sleep();</p><p>  conditionLock.acquire();

41、</p><p><b>  //</b></p><p><b>  }</b></p><p>  public void wake() {</p><p><b>  //</b></p><p>  waitQueue.remove().read

42、y();</p><p><b>  //</b></p><p><b>  }</b></p><p>  3.2.4 測(cè)試代碼及結(jié)果</p><p>  創(chuàng)建共有條件變量c2test,一個(gè)臨界資源count和三個(gè)線程,thread1,thread2,thread3,初始化三個(gè)線程后thread

43、1,thread2調(diào)用c2test.sleep()后開(kāi)始“睡眠”,thread3調(diào)用c2test.wakeAll()喚醒所有線程,thread1,thead2開(kāi)始交替訪問(wèn)臨界資源count并更改其“余額”數(shù)值。</p><p><b>  測(cè)試代碼:</b></p><p>  package nachos.threads;</p><p> 

44、 import nachos.machine.*;</p><p>  public class Condition2Test { </p><p>  Lock condlock = new Lock();</p><p>  Condition2 c2test = new Condition2(condlock);</p><p>  p

45、ublic Condition2Test(){ </p><p><b>  }</b></p><p>  public void simpleCondition2Test(){ </p><p>  System.out.println("\n ****Condition2Test is now executing.***

46、*");</p><p>  System.out.println("初始化賬戶(hù)余額為10000");</p><p>  final MyCount myCount = new MyCount("0000001", 10000); //創(chuàng)建并發(fā)訪問(wèn)的賬戶(hù)</p><p>  KThread thread1 = n

47、ew KThread(new Runnable() {</p><p>  public void run() {</p><p>  new SaveThread("張三", myCount, 2000);</p><p>  System.out.println("張三 goes to sleep");</p>

48、<p>  condlock.acquire();</p><p>  c2test.sleep();</p><p>  System.out.println("張三 reacquires lock when woken.");</p><p>  condlock.release();</p><p> 

49、 System.out.println("張三 is awake!!!");</p><p>  myCount.save(2000," 張三");</p><p><b>  }</b></p><p><b>  });</b></p><p>  KTh

50、read thread2 = new KThread(new Runnable() {</p><p>  public void run() {</p><p>  new SaveThread("李四", myCount, 2000);</p><p>  System.out.println("李四 goes to sleep&

51、quot;);</p><p>  condlock.acquire();</p><p>  c2test.sleep();</p><p>  System.out.println("李四 reacquires lock when woken.");</p><p>  condlock.release();</

52、p><p>  System.out.println("李四 is awake!!!");</p><p>  myCount.save(2000," 李四");</p><p><b>  }</b></p><p><b>  });</b></p&g

53、t;<p>  KThread thread3 = new KThread(new Runnable() {</p><p>  public void run() {</p><p>  System.out.println("thread 3 Waking up the thread");</p><p>  condlock.

54、acquire();</p><p>  c2test.wakeAll();</p><p>  condlock.release();</p><p>  System.out.println("張三 and 李四 woke up by wakeAll");</p><p><b>  }</b>&

55、lt;/p><p><b>  });</b></p><p>  thread1.fork();</p><p>  thread2.fork();</p><p>  thread3.fork();</p><p>  thread1.join();</p><p>  t

56、hread2.join();</p><p>  thread3.join();</p><p>  System.out.println("****Condition2Test finished.****\n");</p><p>  } </p><p><b>  } </b&

57、gt;</p><p>  class SaveThread extends KThread { </p><p>  private String name; //操作人 </p><p>  private MyCount myCount; //賬戶(hù) </p><p>  private int

58、 x; //存款金額 </p><p>  SaveThread(String name, MyCount myCount, int x) { </p><p>  this.name = name; </p><p>  this.myCount = myCount; </p><p>

59、  this.x = x; </p><p><b>  } </b></p><p>  public void run() { </p><p>  myCount.save(x, name); </p><p><b>  } </b></p><p><b>

60、;  } </b></p><p>  class MyCount { </p><p>  private String id; //賬號(hào) </p><p>  private int cash; //賬戶(hù)余額 </p>

61、;<p>  Lock lock = new Lock();//賬戶(hù)鎖 </p><p>  Condition2 c2test = new Condition2(lock);</p><p>  MyCount(String id, int cash) { </p><p>  this.id = id; </p><p

62、>  this.cash = cash; </p><p><b>  } </b></p><p>  public void save(int x, String name) { </p><p>  lock.acquire(); //獲取鎖 </p><p>  if

63、 (x > 0) { </p><p>  cash += x; //存款 </p><p>  System.out.println(name + "存款" + x + ",當(dāng)前余額為" + cash); </p><p><b>  } </b></p

64、><p>  lock.release(); //釋放鎖 </p><p><b>  } </b></p><p><b>  }</b></p><p><b>  測(cè)試結(jié)果:</b></p><p>  3.3 Task1.3 a

65、lram類(lèi)</p><p>  3.3.1 要求分析</p><p>  一個(gè)線程調(diào)用waitUntil(x) 后, 它即被掛起. 在當(dāng)前時(shí)鐘走過(guò)x個(gè)滴答后, 該線程被重新喚醒. 線程被喚醒后并不一定立即進(jìn)入運(yùn)行態(tài), 只要將其放入就緒隊(duì)列中即可. 另外, 多個(gè)線程可以分別調(diào)用waitUntil函數(shù)。</p><p>  3.3.2 設(shè)計(jì)方案</p>&

66、lt;p>  于Alarm類(lèi)有關(guān)的是machine.Timer類(lèi). 它在大約每500個(gè)時(shí)鐘滴答使調(diào)用回調(diào)函數(shù) (由Timer.setInterruptHandler函數(shù)設(shè)置). 因此, Alarm類(lèi)的構(gòu)造函數(shù)中首先要設(shè)置該回調(diào)函數(shù)Alarm.timerInterrupt(). </p><p>  為了實(shí)現(xiàn)waitUntil, 需要在Alarm類(lèi)中實(shí)現(xiàn)一個(gè)隊(duì)列 Alarm.alarmQueue. 隊(duì)列中的每

67、個(gè)項(xiàng)目是 (線程, 喚醒時(shí)間, 相應(yīng)條件變量) 的三元組. 在調(diào)用waitUntil(x) 函數(shù)時(shí), 首先得到關(guān)于</p><p>  以上三元組的信息: (線程: 當(dāng)前線程, 喚醒時(shí)間: 當(dāng)前時(shí)間+x, 新分配的條件變量), 然后將該元組放入隊(duì)列中, 并對(duì)條件變量sleep操作使當(dāng)前線程掛起. 在時(shí)鐘回調(diào)函數(shù)中 (大約每500個(gè)時(shí)鐘間隔調(diào)用一次) 則依次檢查隊(duì)列中的每個(gè)三元組. 如果喚醒時(shí)間大于當(dāng)前時(shí)間, 則將

68、元組移出隊(duì)列并對(duì)元組中的條件變量執(zhí)行wake操作將相應(yīng)線程喚醒. </p><p>  3.3.3 實(shí)現(xiàn)代碼</p><p>  public void timerInterrupt() {</p><p><b>  //</b></p><p>  while(!alarmqueue.isEmpty() &&

69、amp; (alarmqueue.peek().wakeTime <= Machine.timer().getTime())){</p><p>  AlarmThread thread = alarmqueue.remove();</p><p>  thread.waitThread.ready();</p><p><b>  }</b&

70、gt;</p><p><b>  // </b></p><p><b>  }</b></p><p>  public void waitUntil(long x) {</p><p><b>  //</b></p><p>  Alarm

71、Thread thread = new AlarmThread(KThread.currentThread(), wakeTime,conditionlock);</p><p>  alarmqueue.add(thread);</p><p>  KThread.sleep();</p><p><b>  //</b></p>

72、<p><b>  }</b></p><p>  private KThread waitThread;</p><p>  private Condition timecondition;</p><p>  private long wakeTime;</p><p>  3.3.4 測(cè)試代碼及結(jié)果&

73、lt;/p><p>  創(chuàng)建5個(gè)線程,依次“睡眠”20000ticks,線程醒來(lái)后各自打印出睡眠開(kāi)始時(shí)間,要求睡眠時(shí)間,醒來(lái)時(shí)間,以及實(shí)際睡眠時(shí)間。</p><p><b>  測(cè)試代碼: </b></p><p>  public static void selfTest(int numOfTest){</p><p&g

74、t;  Runnable a = new Runnable() {</p><p>  public void run() {</p><p>  AlarmTestThread();</p><p><b>  }</b></p><p><b>  };</b></p><p

75、>  for(int i=0; i<numOfTest; i++){</p><p>  int numOfThreads = 5;</p><p>  print("Creating " + numOfThreads + " num of threads");</p><p>  for(int j=0; j&l

76、t;numOfThreads; j++){</p><p>  KThread thread = new KThread(a);</p><p>  thread.setName("thread");</p><p>  thread.fork(); }</p><p>  ThreadedKernel.alarm.wai

77、tUntil(30000000); </p><p><b>  } </b></p><p><b>  }</b></p><p>  static void AlarmTestThread(){</p><p>  long sleepTime =20000;</p><p

78、>  long timeBeforeSleep = Machine.timer().getTime();</p><p>  ThreadedKernel.alarm.waitUntil(sleepTime);</p><p>  long timeAfterSleep = Machine.timer().getTime();</p><p>  long a

79、ctualSleepTime = timeAfterSleep - timeBeforeSleep;</p><p>  print(KThread.currentThread().toString() + " 被要求在: " + timeBeforeSleep + " 睡眠 " + sleepTime + " ticks");</p>&

80、lt;p>  print(KThread.currentThread().toString() + " 被喚醒時(shí)間: " + Machine.timer().getTime() + "要求睡眠時(shí)間:: " + sleepTime + " ticks, 實(shí)際睡眠時(shí)間: " + actualSleepTime);</p><p><b>  

81、}</b></p><p>  public static void print(String Message) {</p><p>  System.out.println(Message);</p><p><b>  }</b></p><p><b>  測(cè)試結(jié)果:</b><

82、;/p><p>  3.4 Task1.4 communicator類(lèi)</p><p><b>  3.4.1要求分析</b></p><p>  用條件變量實(shí)現(xiàn)Communicator類(lèi)中的speaker()和listen()函數(shù)一個(gè)鎖lock</p><p>  兩個(gè)條件變量speaker(lock),listener(

83、lockw)用來(lái)用來(lái)控制聽(tīng)說(shuō)動(dòng)作。</p><p>  3.4.2 設(shè)計(jì)方案</p><p>  每個(gè)Communicator有一個(gè)鎖 lock(保證操作的原子性) 和與該鎖聯(lián)系的兩個(gè)條件變量用于保證speaker和listener間的同步. 在speak函數(shù)中, 首先檢查若已經(jīng)有一個(gè)speaker在等待(message變量) 或無(wú)listener等待, 則掛起. 否則設(shè)置message變

84、量, 準(zhǔn)備數(shù)據(jù)并喚醒一個(gè)listener. 在listen函數(shù)中, 增加一個(gè)listener后, 若speaker數(shù)目非零且listener數(shù)目為1(及恰好可以配對(duì))首先喚醒speaker, 然后將自己掛起以等待 speaker準(zhǔn)備好數(shù)據(jù)再將自己?jiǎn)拘? 這個(gè)問(wèn)題其實(shí)是一個(gè)緩沖區(qū)長(zhǎng)度為0的生產(chǎn)者/消費(fèi)者問(wèn)題。</p><p>  3.4.3 實(shí)現(xiàn)代碼</p><p>  Communicat

85、or.java</p><p>  int speakersize,listenersize;</p><p>  int Message; </p><p>  Condition speaker,listener;</p><p>  public void speak(int word) {</p><p>&l

86、t;b>  //</b></p><p>  while(speakersize!=0)</p><p>  {speaker.sleep();}</p><p>  this.Message=word;</p><p>  speakersize++;</p><p>  while(listene

87、rsize==0)</p><p>  {speaker.sleep();}</p><p>  listener.wake();</p><p>  speakersize--;</p><p>  speaker.wake();</p><p><b>  //</b></p>

88、<p><b>  }</b></p><p>  public int listen() {</p><p><b>  //</b></p><p>  listenersize++;</p><p>  if(listenersize==1&&speakersize!

89、=0)</p><p>  speaker.wake();</p><p>  listener.sleep();</p><p>  int myMessage = this.Message;</p><p>  listenersize--;</p><p><b>  //</b></

90、p><p>  return myMessage;</p><p><b>  }</b></p><p>  3.4.4 測(cè)試代碼及結(jié)果</p><p><b>  測(cè)試代碼:</b></p><p>  package nachos.threads;</p>&

91、lt;p>  import nachos.machine.*;</p><p>  import java.util.ArrayList;</p><p>  import java.util.Random;</p><p>  public class CommunicatorTest {</p><p>  public Commu

92、nicatorTest(){ </p><p>  Message = 1;</p><p>  numOfSpeakers = 5;</p><p>  numOfListeners = 5;</p><p>  communicator = new Communicator();</p><p><b>

93、  }</b></p><p>  public void commTest(int num){</p><p>  System.out.println("\nCommunicatorTest開(kāi)始"); </p><p>  for (int i=0; i<num; i++){ </p><p>  c

94、reateSpeakers(numOfSpeakers);</p><p>  createListeners(numOfListeners);</p><p>  print("\n 演講者: " + numOfSpeakers);</p><p>  print(" 收聽(tīng)者: " + numOfListeners + &q

95、uot;\n");</p><p>  sleep(numOfSpeakers+numOfListeners);</p><p>  print("\n 演講者與收聽(tīng)者創(chuàng)建完畢");</p><p><b>  }</b></p><p>  print(" Communic

96、ator Test結(jié)束 ");</p><p><b>  }</b></p><p>  public void sleep(int numThreadsCreated){</p><p>  ThreadedKernel.alarm.waitUntil(numThreadsCreated*100);</p><

97、p><b>  }</b></p><p>  public class Listener implements Runnable{</p><p>  public void run(){</p><p>  int messageToRecieve = communicator.listen();</p><p&g

98、t;  System.out.print(Message);</p><p>  print(" " + KThread.currentThread().getName() + " 收到信息 " + messageToRecieve);</p><p><b>  }</b></p><p><

99、b>  }</b></p><p>  public class Speaker implements Runnable{</p><p>  public void run(){</p><p>  communicator.speak(Message++);</p><p>  System.out.print(Mess

100、age);</p><p>  print(" " + KThread.currentThread().getName() + " 發(fā)出信息 " + Message); </p><p><b>  }</b></p><p><b>  }</b&g

101、t;</p><p>  public void createSpeakers(int speakers){</p><p><b>  int j;</b></p><p>  for(j=1; j<=speakers; j++){ </p><p>  KThread speaker

102、Thread = new KThread(new Speaker());</p><p>  speakerThread.setName("Speaker" + j);</p><p>  speakerThread.fork();</p><p><b>  };</b></p><p><b

103、>  }</b></p><p>  public void createListeners(int listeners){</p><p><b>  int k;</b></p><p>  for(k=1; k<=listeners; k++){ </p><p>  KThr

104、ead listenerThread = new KThread(new Listener());</p><p>  listenerThread.setName("Listener" + k);</p><p>  listenerThread.fork(); </p><p><b>  }</b&

105、gt;</p><p><b>  }</b></p><p>  public static void print(String Message) {</p><p>  System.out.println(Message);</p><p><b>  }</b></p><

106、;p>  public static int MAX_THREADS = 245;</p><p>  private int Message; </p><p>  private Communicator communicator;</p><p>  private int numOfSpeakers;</p><p>  pri

107、vate int numOfListeners;</p><p><b>  }</b></p><p><b>  測(cè)試結(jié)果:</b></p><p>  3.5 Task1.5 priority scheduler類(lèi)</p><p>  3.5.1 要求分析</p><p&g

108、t;  實(shí)現(xiàn)優(yōu)先級(jí)調(diào)度。優(yōu)先級(jí)調(diào)度的傳統(tǒng)算法如下: 每個(gè)線程擁有一個(gè)優(yōu)先級(jí) (在Nachos中, 優(yōu)先級(jí)是一個(gè)0到7之間的整數(shù), 默認(rèn)為1, 在線程調(diào)度時(shí), 調(diào)度程序選擇一個(gè)擁有最高優(yōu)先級(jí)的處于就緒狀態(tài)的線程運(yùn)行. 這種算法的問(wèn)題是可能出現(xiàn) “饑餓” 現(xiàn)象: 設(shè)想有一個(gè)低優(yōu)先級(jí)的線程處于臨界區(qū)中運(yùn)行而高優(yōu)先級(jí)的線程在臨界區(qū)外等待. 由于前者優(yōu)先級(jí)較低, 它可能不會(huì)被調(diào)度器選中從而高優(yōu)先級(jí)的線程也不得不浪費(fèi)時(shí)間等待. 需要實(shí)現(xiàn)一種 “讓

109、出” 優(yōu)先級(jí)的機(jī)制 (Priority Donation) : 提高擁有鎖的低優(yōu)先級(jí)線程的優(yōu)先級(jí)以使它迅速完成臨界區(qū), 不使其它較高優(yōu)先級(jí)的線程等待太久. 重新計(jì)算后的優(yōu)先級(jí)稱(chēng)為有效優(yōu)先級(jí), 它可以不斷變化. 以有效優(yōu)先級(jí)為評(píng)判標(biāo)準(zhǔn)。</p><p>  3.5.2 設(shè)計(jì)方案</p><p>  要完善的的PriorityScheduler繼承自Scheduler。</p>

110、<p>  每個(gè)KThread類(lèi)的線程都有一個(gè)ThreadState類(lèi)型的 “線程狀態(tài)” 對(duì)象. 它保存了線程的優(yōu)先級(jí)priority, 有效優(yōu)先級(jí)effectivepriority以及正在等待該線程的線程隊(duì)列IHave,該線程正在等待的線程隊(duì)列Iwant。</p><p>  不同的調(diào)度器有不同類(lèi)型的線程隊(duì)列 (均繼承自ThreadQueue), 線程隊(duì)列由threadstate對(duì)象組成,是否可提高擁

111、有鎖線程優(yōu)先級(jí)取決于創(chuàng)建隊(duì)列時(shí)transferPriority的值,它有兩個(gè)重要方法: waitForAccess (KThread thread) 和 acquire (KThread thread). 前者將一個(gè)線程加入等待隊(duì)列(實(shí)際上加入的是該線程的線程狀態(tài)); 后者將一個(gè)線程從等待隊(duì)列中取出, 表示該線程當(dāng)前處于運(yùn)行狀態(tài). 這兩個(gè)方法中, 首先找出相應(yīng)線程的線程狀態(tài), 再對(duì)線程狀態(tài)執(zhí)行相應(yīng)的waitForAccess和acqui

112、re操作 (對(duì)隊(duì)列的真正操作是在ThreadState.waitForAccess和ThreadState.acquire中完成的). </p><p>  設(shè)置, 返回, 增加, 減少優(yōu)先級(jí)的函數(shù)在Scheduler中. ThreadQueue.nextThread 返回當(dāng)前隊(duì)列中有效優(yōu)先級(jí)最高的線程以運(yùn)行之. 而對(duì)某線程有效優(yōu)先級(jí)的計(jì)算在ThreadState.getEffectivePriority中. 當(dāng)

113、該線程沒(méi)有正在等待該線程的線程隊(duì)列時(shí),其有效優(yōu)先級(jí)等于其原始優(yōu)先級(jí),不然其有效優(yōu)先級(jí)增加到不小于其等待隊(duì)列IHave中各線程的有效優(yōu)先級(jí)的最大值。它也有兩個(gè)重要方法: waitForAccess (PriorityQueue waitQueue) 和 acquire (PriorityQueue waitQueue). 前者將waitqueue從IHave中移出(如果有的話),加入到Iwant中;后者將waitqueue從Iwant中移

114、出(如果有的話),加入到IHave中。</p><p>  3.5.3 實(shí)現(xiàn)代碼</p><p>  實(shí)現(xiàn)代碼見(jiàn)PriorityScheduler.java</p><p>  3.5.4 測(cè)試代碼及結(jié)果</p><p>  測(cè)試方法:創(chuàng)建兩個(gè)可捐贈(zèng)優(yōu)先級(jí)q1,q2及一個(gè)不可捐贈(zèng)優(yōu)先級(jí)隊(duì)列q3,三個(gè)優(yōu)先級(jí)分別高中低線程l,m,h。第一次將l,

115、m加到q1隊(duì)列,l,m加到q2隊(duì)列,測(cè)試q1的nextthread是m。分別測(cè)試優(yōu)先級(jí)是否“捐贈(zèng)”,低優(yōu)先級(jí)線程提告優(yōu)先級(jí)后是否被選中執(zhí)行。</p><p><b>  測(cè)試代碼:</b></p><p>  package nachos.threads;</p><p>  import nachos.machine.*;</p>

116、<p>  import nachos.threads.*;</p><p>  import java.util.*;</p><p>  public final class PrioritySchedulerTest {</p><p><b>  /**</b></p><p>  * A very

117、 simple test of priority donation.</p><p><b>  */</b></p><p>  public static void simplePrioritySchedulerTest() {</p><p>  final boolean intStatus = Machine.interrupt().

118、disable();</p><p>  final Scheduler s = new PriorityScheduler();</p><p>  // Enable priority donation.</p><p>  final ThreadQueue q1 = s.newThreadQueue(false);</p><p> 

119、 final ThreadQueue q2 = s.newThreadQueue(false);</p><p>  final ThreadQueue q3 = s.newThreadQueue(true);</p><p>  final Runnable dummyRunnable = new Runnable() {</p><p>  public voi

120、d run() {</p><p>  // do nothing</p><p><b>  }</b></p><p><b>  };</b></p><p>  // Create dummy Threads</p><p>  final KThread lowPr

121、iorityThread = new KThread(dummyRunnable);</p><p>  final KThread mediumPriorityThread = new KThread(dummyRunnable);</p><p>  final KThread highPriorityThread = new KThread(dummyRunnable);</p

122、><p>  // Link dummy Threads with dummy ThreadState</p><p>  s.setPriority(lowPriorityThread, PriorityScheduler.priorityMinimum);</p><p>  s.setPriority(mediumPriorityThread, PriorityS

123、cheduler.priorityDefault);</p><p>  s.setPriority(highPriorityThread, PriorityScheduler.priorityMaximum);</p><p>  // Test that effectivePriorities start as the initial priorities</p><

124、;p>  Lib.assertTrue(s.getEffectivePriority(lowPriorityThread) == PriorityScheduler.priorityMinimum);</p><p>  Lib.assertTrue(s.getEffectivePriority(mediumPriorityThread) == PriorityScheduler.priorityDefau

125、lt);</p><p>  Lib.assertTrue(s.getEffectivePriority(highPriorityThread) == PriorityScheduler.priorityMaximum);</p><p>  // Low priority and Medium priority thread are on the ready queue</p>

126、;<p>  q1.waitForAccess(lowPriorityThread);</p><p>  q1.waitForAccess(mediumPriorityThread);</p><p>  q2.waitForAccess(lowPriorityThread);</p><p>  q2.waitForAccess(mediumPri

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論