版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p> 操作系統(tǒng)課程設(shè)計(jì)——讀者寫者問題</p><p><b> 一、實(shí)習(xí)要求</b></p><p> 在windows 2000環(huán)境下,創(chuàng)建一個(gè)控制臺(tái)進(jìn)程,此進(jìn)程包含n個(gè)線程。用這n個(gè)線程來表示n個(gè)讀者或?qū)懻摺C總€(gè)線程按相應(yīng)測(cè)試數(shù)據(jù)文件(后面有介紹)的要求進(jìn)行讀寫操作。用信號(hào)量機(jī)制分別實(shí)現(xiàn)讀者優(yōu)先和寫者優(yōu)先的讀者—寫者問題。</p>
2、<p> 讀者—寫者問題的讀寫操作限制(包括讀者優(yōu)先和寫者優(yōu)先):</p><p> 1)寫—寫互斥,即不能有兩個(gè)寫者同時(shí)進(jìn)行寫操作。</p><p> 2)讀—寫互斥,即不能同時(shí)有一個(gè)線程在讀,而另一個(gè)線程在寫。</p><p> 3)讀—讀允許,即可以有一個(gè)或多個(gè)讀者在讀。</p><p> 讀者優(yōu)先的附加限制:如
3、果一個(gè)讀者申請(qǐng)進(jìn)行讀操作時(shí)已有另一個(gè)讀者正在進(jìn)行讀操作,則該讀者可直接開始讀操作。</p><p> 寫者優(yōu)先的附加限制:如果一個(gè)讀者申請(qǐng)進(jìn)行讀操作時(shí)已有另一寫者在等待訪問共享資源,則該讀者必須等到?jīng)]有寫者處于等待狀態(tài)后才能開始讀操作。</p><p> 運(yùn)行結(jié)果顯示要求:要求在每個(gè)線程創(chuàng)建、發(fā)出讀寫操作申請(qǐng)、開始讀寫操作和結(jié)束讀寫操作時(shí)分別顯示一行提示信息,以確定所有處理都遵守相應(yīng)的
4、讀寫操作限制。</p><p> 二、測(cè)試數(shù)據(jù)文件格式</p><p> 測(cè)試數(shù)據(jù)文件包括n行測(cè)試數(shù)據(jù),分別描述創(chuàng)建的n個(gè)線程是讀者還是寫者,以及讀寫操作的開始時(shí)間和持續(xù)時(shí)間。每行測(cè)試數(shù)據(jù)包括四個(gè)字段,各個(gè)字段間用空格分隔。第—字段為—個(gè)正整數(shù),表示線程序號(hào)。第二字段表示相應(yīng)線程角色,R表示讀者,W表示寫者。第三字段為一個(gè)正數(shù),表示讀寫操作的開始時(shí)間:線程創(chuàng)建后,延遲相應(yīng)時(shí)間(單位為秒
5、)后發(fā)出對(duì)共享資源的讀寫申請(qǐng)。第四字段為一個(gè)正數(shù),表示讀寫操作的持續(xù)時(shí)間。當(dāng)線程讀寫申請(qǐng)成功后,開始對(duì)共享資源的讀寫操作,該操作持續(xù)相應(yīng)時(shí)間后結(jié)束,并釋放共享資源。</p><p> 下面是—個(gè)測(cè)試數(shù)據(jù)文件的例子:</p><p><b> 1 R 3 5</b></p><p><b> 2 W 4 5</b>&l
6、t;/p><p><b> 3 R 5 2</b></p><p><b> 4 R 6 5</b></p><p><b> 5 W 5.1 3</b></p><p> 注意 在創(chuàng)建數(shù)據(jù)文件時(shí),由于涉及到文件格式問題,最好在記事本中手工逐個(gè)鍵入數(shù)據(jù),而不要拷貝粘貼數(shù)據(jù)
7、,否則,本示例程序運(yùn)行時(shí)可能會(huì)出現(xiàn)不可預(yù)知的錯(cuò)誤。</p><p><b> 三、實(shí)習(xí)分析</b></p><p> 可以將所有讀者和所有寫者分別存于一個(gè)讀者等待隊(duì)列和一個(gè)寫者等待隊(duì)列中,每當(dāng)讀允許時(shí),就從讀者隊(duì)列中釋放一個(gè)或多個(gè)讀者線程進(jìn)行讀操作;每當(dāng)寫允許時(shí),就從寫者隊(duì)列中釋放一個(gè)寫者進(jìn)行寫操作。</p><p><b>
8、1.讀者優(yōu)先</b></p><p> 讀者優(yōu)先指的是除非有寫者在寫文件,否則讀者不需要等待。所以可以用—個(gè)整型變量readcount記錄當(dāng)前的讀者數(shù)目,用于確定是否需要釋放正在等待的寫者線程(當(dāng)readcount=0時(shí),表明所有的讀者讀完,需要釋放寫者等待隊(duì)列中的一個(gè)寫者)。每一個(gè)讀者開始讀文件時(shí),必須修改readcount變量。因此需要一個(gè)互斥對(duì)象mutex來實(shí)現(xiàn)對(duì)全局變量readcount修改
9、時(shí)的互斥。</p><p> 另外,為了實(shí)現(xiàn)寫—寫互斥,需要增加一個(gè)臨界區(qū)對(duì)象RP_Write。當(dāng)寫者發(fā)出寫請(qǐng)求時(shí),必須申請(qǐng)臨界區(qū)對(duì)象的所有權(quán)。通過這種方法,也可以實(shí)現(xiàn)讀—寫互斥、當(dāng)readcount=1時(shí)(即第一個(gè)讀者到來時(shí)),讀者線程也必須申請(qǐng)臨界區(qū)對(duì)象的所有權(quán)。</p><p> 當(dāng)讀者擁有臨界區(qū)的所有權(quán)時(shí),寫者阻塞在臨界區(qū)對(duì)象RP_Write上。當(dāng)寫者擁有臨界區(qū)的所有權(quán)時(shí),第一
10、個(gè)讀者判斷完“readcount= =1”后阻塞在write上,其余的讀者由于等待對(duì)readcount的判斷,阻塞在mutex上。</p><p> 2.寫者優(yōu)先(請(qǐng)根據(jù)自己編寫的寫者優(yōu)先程序進(jìn)行分析)</p><p> 四、相關(guān)API函數(shù)說明</p><p> 1.CreateThread</p><p><b> 函數(shù)功
11、能:</b></p><p> 該函數(shù)創(chuàng)建一個(gè)在調(diào)用進(jìn)程的地址空間中執(zhí)行的線程。</p><p><b> 函數(shù)原型:</b></p><p> HANDLE CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes,</p><p> DWORD
12、dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress,</p><p> LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);</p><p><b> 參數(shù):</b></p><p> ·lpThreadA
13、ttributes:指向一個(gè)LPSECURITY_ATTRIBUTES結(jié)構(gòu)。該結(jié)構(gòu)決定了返回的句柄是否可被子進(jìn)程繼承。若lpThreadAttributes為NULL,則句柄不能被繼承。</p><p> 在Windows NT中該結(jié)構(gòu)的lpSecurityDescriptor成員定義了新進(jìn)程的安全性描述符。若lpThreadAttributes為NULL。則線程獲得—個(gè)默認(rèn)的安全性描述符。</p>
14、<p> ·dwStackSize:定義原始堆棧提交時(shí)的大小(按字節(jié)計(jì))。系統(tǒng)將該值舍入為最近的頁(yè)。若該值為0,或小于默認(rèn)時(shí)提交的大小,默認(rèn)情況是使用與調(diào)用線程同樣的大?。嗟男畔?,請(qǐng)看Thread Stack Size。</p><p> ·lpStartAddress:指向一個(gè)LPTHREAD_START_ROUTINE類型的應(yīng)用定義的函數(shù),該線程執(zhí)行此函數(shù)。該指針還表
15、示遠(yuǎn)程進(jìn)程中線程的起始地址。該函數(shù)必須存在于遠(yuǎn)程進(jìn)程中。</p><p> ·lpParameter:定義一個(gè)傳遞給該進(jìn)程的32位值。</p><p> ·dwCreationFlags:定義控制進(jìn)程創(chuàng)建的附加標(biāo)志。若定義了CREATE_SUSPENDED標(biāo)志,線程創(chuàng)建時(shí)處于掛起狀態(tài),并且直到ResumeThread函數(shù)調(diào)用時(shí)才能運(yùn)行。若該值為0,則該線程在創(chuàng)建后立
16、即執(zhí)行。</p><p> ·lpThreadId:指向—個(gè)32位值,它接收該線程的標(biāo)識(shí)符。</p><p><b> 返回值:</b></p><p> 若函數(shù)調(diào)用成功,返回值為新線程的句柄;若函數(shù)調(diào)用失敗,返回值為NULL。</p><p><b> 備注:</b></p
17、><p> 新進(jìn)程的句柄創(chuàng)建時(shí)設(shè)為THREAD_ALL_ACCESS訪問權(quán)限。若未提供安全性描述符,則該句柄可被任何要求一個(gè)線程對(duì)象句柄的函數(shù)所使用。若提供了安全性描述符,則以后使用該句柄時(shí),將在授權(quán)訪問以前執(zhí)行訪問檢查。若訪問檢查拒絕訪問,則請(qǐng)求進(jìn)程不能使用該句柄獲得對(duì)該線程的訪問。</p><p> 線程從lpStartAddress參數(shù)定義的函數(shù)處開始執(zhí)行。若該函數(shù)返回,系統(tǒng)將默認(rèn)地
18、認(rèn)為以調(diào)用ExitThread函數(shù)的方法終止該線程。使用GetExitcodeThread函數(shù)來獲得線程的返回值。</p><p> 線程創(chuàng)建時(shí)擁有THREAD_PRIORITY_NORMAL優(yōu)先權(quán)。使用GetThreadPriority和SetThreadPriority函數(shù)可以獲得和設(shè)置線程的優(yōu)先權(quán)值。</p><p> 一個(gè)線程終止時(shí)。該線程對(duì)象被設(shè)為發(fā)信號(hào)狀態(tài),以滿足在該對(duì)象上
19、等待的所有進(jìn)程。</p><p> 一個(gè)線程對(duì)象始終存在于系統(tǒng)中,直到該線程終止,且它所有的句柄都已通過調(diào)用CloseHandle函數(shù)關(guān)閉。</p><p> 2.ExitThread</p><p><b> 函數(shù)功能:</b></p><p> 該函數(shù)結(jié)束一個(gè)線程。</p><p>&
20、lt;b> 函數(shù)原型:</b></p><p> VOID ExitThread (DWORD dwExitCode);</p><p><b> 參數(shù):</b></p><p> ·dwExitCode:定義調(diào)用線程的退出代碼。使用GetExitCodeThread函數(shù)來檢測(cè)一個(gè)線程的退出代碼。</p
21、><p><b> 返回值:無(wú)。</b></p><p><b> 備注:</b></p><p> 調(diào)用ExitThread函數(shù),是結(jié)束—個(gè)線程的較好的方法。調(diào)用該函數(shù)后(或者直接地調(diào)用,或者從一個(gè)線程過程返回),當(dāng)前線程的堆棧取消分配,線程終止。若調(diào)用該函數(shù)時(shí),該線程為進(jìn)程的最后一個(gè)線程,則該線程的進(jìn)程也被終止。&l
22、t;/p><p> 線程對(duì)象的狀態(tài)變?yōu)榘l(fā)信號(hào)狀態(tài),以釋放所有正在等待該線程終止的其他線程。線程的終止?fàn)顟B(tài)從STILL_ACTIVATE變?yōu)閐wExitCode參數(shù)的值。</p><p> 線程結(jié)束時(shí)不必從操作系統(tǒng)中移去該線程對(duì)象。當(dāng)線程的最后一個(gè)句柄關(guān)閉時(shí),該線程對(duì)象被刪除。</p><p><b> 3.Sleep</b></p>
23、;<p><b> 函數(shù)功能:</b></p><p> 該函數(shù)對(duì)于指定的時(shí)間間隔掛起當(dāng)能的執(zhí)行線程。</p><p><b> 函數(shù)原型:</b></p><p> VOID Sleep (DWORD dwMulliseconds);</p><p><b> 參
24、數(shù):</b></p><p> ·dwMilliseconds:定義掛起執(zhí)行線程的時(shí)間,以毫秒(ms)為單位。取值為0時(shí),該線程將余下的時(shí)間片交給處于就緒狀態(tài)的同一優(yōu)先級(jí)的其他線程。若沒有處于就緒狀態(tài)的同一優(yōu)先級(jí)的其他線程,則函數(shù)立即返回,該線程繼續(xù)執(zhí)行。若取值為INFINITE則造成無(wú)限延遲。</p><p><b> 返回值:</b>&l
25、t;/p><p><b> 該函數(shù)沒有返回值。</b></p><p><b> 備注:</b></p><p> 一個(gè)線程可以在調(diào)用該函數(shù)時(shí)將睡眠時(shí)間設(shè)為0ms,以將剩余的時(shí)間片交出。</p><p> 4.CreateMutex</p><p><b>
26、函數(shù)功能:</b></p><p> 該函數(shù)創(chuàng)建有名或者無(wú)名的互斥對(duì)象。</p><p><b> 函數(shù)原型:</b></p><p> HANDLE CreateMutex (LPSECURITY_ATTRIBUTES lpMutexAttributes,</p><p> BOOL bInitia
27、lOwner, LPCTSTR lpName);</p><p><b> 參數(shù):</b></p><p> ·lpMutexAttributes:指向SECURITY_ATTRIBUTES結(jié)構(gòu)的指針,該結(jié)構(gòu)決定子進(jìn)程是否能繼承返回句柄。如果lpMutexAttributes為NULL,那么句柄不能被繼承。</p><p> 在
28、Windows NT中該結(jié)構(gòu)的LpSecuriyDescriptor成員指定新互斥對(duì)象的安全描述符。如果lpMutexAttributes為NULL,那么互斥對(duì)象獲得默認(rèn)的安全描述符。</p><p> ·bInitialOwner:指定互斥對(duì)象的初始所屬身份。如果該值為TRUE,并且調(diào)用者創(chuàng)建互斥對(duì)象,那么調(diào)用線程獲得互斥對(duì)象所屬身份。否則,調(diào)用線程不能獲得互斥對(duì)象所屬身份。判斷調(diào)用者是否創(chuàng)建互斥對(duì)
29、象清參閱返回值部分。</p><p> ·lpName:指向以NULL結(jié)尾的字符串,該字符串指定了互斥對(duì)象名。該名字的長(zhǎng)度小于MAX_PATH且可以包含除反斜線(\)路徑分隔符以外的任何字符。名字是區(qū)分大小寫的。</p><p> 如果lpName與已存在的有名互斥對(duì)象名相匹配,那么該函數(shù)要求用MUTEX_ALL_ACCESS權(quán)限訪問已存在的對(duì)象。在這種情況下,由于參數(shù)bIn
30、itialOwner已被創(chuàng)建進(jìn)程所設(shè)置,該參數(shù)被忽略。如果參數(shù)lpMutexAttributes不為NULL,它決定句柄是否解除繼承,但是其安全描述符成員被忽略。</p><p> 如果lpName為NULL,那么創(chuàng)建的互斥對(duì)象無(wú)名。</p><p> 如果lpName與已存在的事件、信號(hào)量、可等待定時(shí)器、作業(yè)或者義件映射對(duì)象的名字相匹配,那么函數(shù)調(diào)用失敗,并且 GetLastErro
31、r函數(shù)返回ERROR_ALREADY_HANDLE,其原因是這些對(duì)象共享相同的名字空間。</p><p><b> 返回值:</b></p><p> 如果函數(shù)調(diào)用成功,返回值是互斥對(duì)象句柄;如果函數(shù)調(diào)用之前,有名互斥對(duì)象已存在,那么函數(shù)給已存在的對(duì)象返回一個(gè)句柄,并且函數(shù)GetLastError返回ERROR_ ALREADY_EXISTS。否則,調(diào)用者創(chuàng)建互斥
32、對(duì)象。</p><p> 如果函數(shù)調(diào)用失敗,則返回值為NULL。若想獲得更多錯(cuò)誤信息,請(qǐng)調(diào)用GetLastError函數(shù)。</p><p><b> 備注:</b></p><p> 由函數(shù)CreateMutex返回的句柄有MUTEX_ALL_ACCESS權(quán)限可以去訪問新的互斥對(duì)象,并且可用在請(qǐng)求互斥對(duì)象句柄的任何函數(shù)中。</p&g
33、t;<p> 調(diào)用進(jìn)程中的任何線程可以在調(diào)用等待函數(shù)時(shí)指定互斥對(duì)象句柄。當(dāng)指定對(duì)象的狀態(tài)為信號(hào)態(tài)時(shí)。返回單對(duì)象等待函數(shù)。當(dāng)任何一個(gè)或者所有的互斥對(duì)象都為信號(hào)態(tài)時(shí),返回多對(duì)象等待函數(shù)指令。等待函數(shù)返回后,等待的線程被釋放,繼續(xù)向下執(zhí)行。</p><p> 當(dāng)一個(gè)互斥對(duì)象不被任何線程擁有時(shí),處于信號(hào)態(tài)。創(chuàng)建該對(duì)象的線程可以使用bInitialOwner標(biāo)志來請(qǐng)求立即獲得對(duì)該互斥對(duì)象的所有權(quán)。否則,線
34、程必須使用等待函數(shù)來請(qǐng)求所有權(quán)。當(dāng)互斥對(duì)象處于信號(hào)態(tài),等待的線程獲得對(duì)該對(duì)象的所有權(quán)時(shí),此互斥對(duì)象的狀態(tài)被設(shè)置為非信號(hào)態(tài),等待函數(shù)返回。任意時(shí)刻,僅有一個(gè)線程能擁有該互斥對(duì)象.線程可以使用ReleaseMutex函數(shù)來釋放對(duì)這個(gè)互斥對(duì)象的所有權(quán)。</p><p> 總線程已經(jīng)擁有了—個(gè)互斥對(duì)象,那么它可以重復(fù)調(diào)用等待函數(shù)而不會(huì)發(fā)生阻塞,一般情況下,用戶不會(huì)重復(fù)等待同一個(gè)互斥對(duì)象,這種機(jī)制防止了線程因等待它已經(jīng)擁
35、有的互斥對(duì)象而發(fā)生死鎖。然而,線程必須為每一次等待調(diào)用—次ReleaseMutex函數(shù)來釋放該互斥對(duì)象。</p><p> 兩個(gè)或多個(gè)進(jìn)程可以調(diào)用CreateMutex來創(chuàng)建同名的互斥對(duì)象,第一個(gè)進(jìn)程實(shí)際創(chuàng)建互斥對(duì)象.以后的進(jìn)程打開已存在的互斥對(duì)象的句柄。這使得多個(gè)進(jìn)程可以得到同一個(gè)互斥對(duì)象的句柄,從而減輕了用戶的負(fù)擔(dān),使用戶不必判斷創(chuàng)建進(jìn)程是否為第一個(gè)啟動(dòng)的進(jìn)程。使用這種技術(shù)時(shí),應(yīng)該把bInitialOwne
36、r標(biāo)志設(shè)為FALSE;否則很難確定開始時(shí)哪一個(gè)進(jìn)程擁有該互斥對(duì)象。</p><p> 由于多進(jìn)程能夠擁有相同互斥對(duì)象的句柄,通過使用這個(gè)對(duì)象,可使多進(jìn)程同步。以下為共享對(duì)象機(jī)制:</p><p> ·如果CreateMutex中的lpMutexAttributes參數(shù)允許繼承,由CreateProcess函數(shù)創(chuàng)建的子進(jìn)程可以繼承父近程的互斥對(duì)象句柄。</p>&
37、lt;p> ·一個(gè)進(jìn)程可以在調(diào)用DuplicateHandle函數(shù)時(shí)指定互斥對(duì)象句柄來創(chuàng)建一個(gè)可以被其他進(jìn)程使用的雙重句柄。一個(gè)進(jìn)程在調(diào)用OpenMutex或CreateMutex函數(shù)時(shí)能指定互斥對(duì)象名。</p><p> ·使用CloseHandle函數(shù)關(guān)閉句柄,進(jìn)程結(jié)束時(shí)系統(tǒng)自動(dòng)關(guān)閉句柄。當(dāng)最后一個(gè)句柄被關(guān)閉時(shí),互斥對(duì)象被銷毀。</p><p> 5.R
38、eleaseMutex</p><p><b> 函數(shù)功能:</b></p><p> 該函數(shù)放棄指定互斥對(duì)象的所有權(quán)。</p><p><b> 函數(shù)原型:</b></p><p> BOOL ReleaseMutex (HANDLE hMutex);</p><p&g
39、t;<b> 參數(shù):</b></p><p> ·hMutex:互斥對(duì)象句柄。為CreateMutex或OpenMutex函數(shù)的返回值。</p><p><b> 返回值:</b></p><p> 如果函數(shù)調(diào)用成功,那么返回值是非零值;如果函數(shù)調(diào)用失敗,那么返回值是零值。若想獲得更多錯(cuò)誤信息,請(qǐng)調(diào)用Ge
40、tLastError函數(shù)。</p><p><b> 備注:</b></p><p> 如果調(diào)用線程不擁有互斥對(duì)象,ReleaseMutex函數(shù)失敗。</p><p> 一個(gè)線程通過調(diào)用等待函數(shù)擁有互斥對(duì)象。創(chuàng)建該互斥對(duì)象的線程也擁有互斥對(duì)象。而不需要調(diào)用等待函數(shù)。當(dāng)互斥對(duì)象的所有者線程不再需要互斥對(duì)象時(shí),它可以調(diào)用ReleaseMute
41、x函數(shù)。</p><p> 當(dāng)—個(gè)線程擁有—個(gè)互斥對(duì)象后,它可以用該互斥對(duì)象多次調(diào)用等待函數(shù)而不會(huì)阻塞。這防止一個(gè)線程等待一個(gè)它已擁有的互斥對(duì)象時(shí)出現(xiàn)死鎖。不過,為了釋放所有權(quán),該線程必須為每一個(gè)等待操作調(diào)用一次ReleaseMutex函數(shù);</p><p> 6.WaitForSingleObject</p><p><b> 函數(shù)功能:</
42、b></p><p> 當(dāng)下列情況之一發(fā)生時(shí)該函數(shù)返回:(1)指定對(duì)象處于信號(hào)態(tài);(2)超時(shí)。</p><p><b> 函數(shù)原型:</b></p><p> DWORD WaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds);</p><p>&
43、lt;b> 參數(shù):</b></p><p> ·hHandle:等待對(duì)象句柄。若想了解指定句柄的對(duì)象類型列表,參閱下面?zhèn)渥⒉糠帧?lt;/p><p> 在WindowsNT中,句柄必須有SYNCHRONIZE訪問權(quán)限。若想獲得更多的信息,請(qǐng)查看Standard Access Rights。</p><p> ·dwMilli
44、seconds:指定以毫秒為單位的超時(shí)間隔。如果超時(shí),即使對(duì)象的狀態(tài)是非信號(hào)態(tài)的并且沒有完成,函數(shù)也返回。如果dwMillseconds是0,函數(shù)測(cè)試對(duì)象的狀態(tài)并立刻返回;如果dwMillseconds是INFINITE,函數(shù)從不超時(shí)。</p><p><b> 返回值:</b></p><p> 如果函數(shù)調(diào)用成功,返回值表明引起函數(shù)返回的事件。可能值如下:<
45、;/p><p> WAIT_ABANDONED:指定對(duì)象是互斥對(duì)象,在線程被終止前,線程沒有釋放互斥對(duì)象?;コ鈱?duì)象的所屬關(guān)系被授予調(diào)用線程,并且該互斥對(duì)象被置為非信號(hào)態(tài)。</p><p> WAIT_OBJECT_0:指定對(duì)象的狀態(tài)被置為信號(hào)態(tài)。</p><p> WAIT_TIMEOUT:超時(shí),并且對(duì)象的狀態(tài)為非信號(hào)態(tài)。</p><p>
46、 如果函數(shù)調(diào)用失敗,返回值是WAIT_FAILED。若想獲得更多錯(cuò)誤信息,請(qǐng)調(diào)用GetLastError函數(shù)。</p><p><b> 備注:</b></p><p> WaitForSingleObjects函數(shù)決定等待條件是否被滿足。如果等待條件并沒有被滿足,調(diào)用線程進(jìn)入—個(gè)高效的等待狀態(tài),當(dāng)?shù)却凉M足條件時(shí)占用非常少的處理器時(shí)間。</p>&
47、lt;p> 在運(yùn)行前。一個(gè)等待函數(shù)修改同步對(duì)象類型的狀態(tài)。修改僅發(fā)生在引起函數(shù)返回的對(duì)象身上。例如,信號(hào)得計(jì)數(shù)減1。</p><p> WaitForSingleObjects函數(shù)能等待的對(duì)象包括:Change notification(改變通告):Console input(控制臺(tái)輸入);Event(事件);Job(作業(yè));Mutex(互斥對(duì)象);Process(進(jìn)程);Semaphore(信號(hào)量);
48、Thread(線程);Waitable timer (可等待定時(shí)器)。</p><p> 當(dāng)使用等待函數(shù)或代碼直接或間接創(chuàng)建窗口時(shí),一定要小心。如果一個(gè)線程創(chuàng)建了任何窗口,它必須處理進(jìn)程消息。消息廣播被發(fā)送到系統(tǒng)的所有窗口。一個(gè)線程用沒有超時(shí)的等待函數(shù)也許會(huì)引起系統(tǒng)死鎖。間接創(chuàng)建窗口的兩個(gè)例子是DDE和COM CoInitialize。因此,如果用戶有一個(gè)創(chuàng)建窗口的線程,用MsgWaitForMultipleO
49、bjects或MsgWaitForMultipleObjectEx函數(shù),而不要用SignalObjectAndWait函數(shù)。</p><p> 7.WaitForMultipleObjects</p><p><b> 函數(shù)功能:</b></p><p> WaitForMultipleObjects函數(shù)當(dāng)下列條件之一滿足時(shí)返回:(1)任
50、意一個(gè)或全部指定對(duì)象處于信號(hào)態(tài);(2)超時(shí)間隔已過。</p><p><b> 函數(shù)原型:</b></p><p> DWORD WaitForMultipleObjects (DWORD nCount, CONST HANDLE *lpHandles,</p><p> BOOL fWaitAll, DWORD dwMillisecon
51、ds);</p><p><b> 參數(shù):</b></p><p> ·nCount:指定由lpHandles所指向的數(shù)組中的句柄對(duì)象數(shù)目最大對(duì)象句柄數(shù)目MAXIMUM_WAIT_OBJECTS。</p><p> ·lpHandles:指向?qū)ο缶浔鷶?shù)組的指針。該數(shù)組可以包含不同類型對(duì)象的句柄。在WindowsNT中,
52、該句柄必須有SYNCHRONIZE訪問權(quán)限。若想獲得更多的信息,請(qǐng)查看Standard Access Rights。</p><p> ·fWaitAll:指定等待類型。如果為TRUE,當(dāng)lpHandles指向的數(shù)組里的全部對(duì)象為信號(hào)態(tài)時(shí),函數(shù)返回。如果為FALSE,當(dāng)由lpHandles指向的數(shù)組里的任—對(duì)象為信號(hào)態(tài)時(shí),函數(shù)返回。對(duì)于后者,返回值指出引起函數(shù)返回的對(duì)象。</p><
53、;p> ·dwMilliseconds:指定以毫秒為單位的超時(shí)間隔。如果超時(shí),即使bWaitAll參數(shù)指定的條件沒有滿足,函數(shù)也返回。如果dwMilliseconds是0,函數(shù)測(cè)試指定對(duì)象的狀態(tài)并立刻返回。如果dwMilliseconds是INFINITE,函數(shù)從不超時(shí)。</p><p><b> 返回值;</b></p><p> 如果函數(shù)調(diào)用
54、成功,返回值表明引起函數(shù)返回的事件。可能值如下:</p><p> WAIT_OBJECT_0到WAIT_OB JECT0+ nCount-1:如果bWaitAll為TRUE,那么返回值表明所有指定對(duì)象的狀態(tài)為信號(hào)態(tài)。如果bWaitAll為FALSE,那么返回值減去WAIT_OBJECT_0表明引起函數(shù)返回的對(duì)象的pHandles數(shù)組索引。如果多于一個(gè)對(duì)象變?yōu)樾盘?hào)態(tài),則返回的是數(shù)組索引最小的信號(hào)態(tài)對(duì)象索引。&l
55、t;/p><p> WAIT_ABANDONED_0到WAIT_ABANDONED_0+nCount-1:如果bWaitAll為TRUE,那么返回值表明所有指定對(duì)象的狀態(tài)為信號(hào)態(tài),并且至少一個(gè)對(duì)象是己放棄的互斥對(duì)象。如果bWaitAll為FALSE,那么返回值減去WAIT_ABANDONED_0表明引起函數(shù)返回的放棄互斥對(duì)象的pHandles數(shù)組索引。</p><p> WAIT_TIME
56、OUT:超時(shí)并且由參數(shù)bWaitAll指定的條件沒有滿足。</p><p> 如果函數(shù)調(diào)用失敗,返回值是WAIT_FAILED。若想獲得更多錯(cuò)誤信息,請(qǐng)調(diào)用GetLastError函數(shù)。</p><p> 8.CreateSemapore</p><p><b> 函數(shù)功能:</b></p><p> 該函數(shù)是創(chuàng)
57、建一個(gè)有名或者無(wú)名信號(hào)對(duì)象。</p><p><b> 函數(shù)原型:</b></p><p> HANDLE CreatSemaphore(LPSECURITY_ATTRIBUTES lpAttributes,</p><p> LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName);
58、</p><p><b> 參數(shù);</b></p><p> ·LpAttributes:安全屬性。如果是NULL就表示要使用默認(rèn)屬性。</p><p> ·lInitialCount:Semaphore的初值。必須大于或等于0,并且小于或等于MaxmumCount。</p><p>
59、83;lMaximumCount:Semaphore的最大值。這也就是在同一時(shí)間內(nèi)能夠鎖住Semaphore之線程的最多個(gè)數(shù)。</p><p> ·lpName:Semaphore的名稱(一個(gè)字符串)。任何線程(或進(jìn)程)都可以根據(jù)這一名稱引用到這個(gè)Semaphore。這個(gè)值可以是NULL,意思是產(chǎn)生—個(gè)沒有名字的Semaphore。</p><p><b> 返回值
60、:</b></p><p> 如果成功就傳回一個(gè)handle,否則傳回NULL。不論哪一種情況,GetLastError都會(huì)傳回一個(gè)合理的結(jié)果。如果指定的Semaphore名稱已經(jīng)存在,則該函數(shù)還是成功的,GetLastError會(huì)傳回ERROR_ALREADY_EXISTS。</p><p> 9.ReleaseSemaphore</p><p>
61、<b> 函數(shù)功能:</b></p><p> 該函數(shù)將指定信號(hào)對(duì)象的計(jì)數(shù)增加—個(gè)指定的數(shù)量。</p><p><b> 函數(shù)原型:</b></p><p> BOOL ReleaseSemaphore (HANDLE hSemaphore, LONG lReleaseCount,</p><p
62、> LPLONG lpPreviousCount);</p><p><b> 參數(shù):</b></p><p> ·hSemaphore:Semaphore的handle。</p><p> ·lReleaseCount:Semaphore現(xiàn)值的增額。該值不可以是負(fù)值或0。</p><p&g
63、t; ·lpPreviousCount:借此返回Semaphore原來的值。</p><p><b> 返回值:</b></p><p> 如果成功,則返回TRUE。否則返回FALSE。失敗時(shí)可調(diào)用GetLastError獲得原因。</p><p> 無(wú)論ReleaseSemaphore對(duì)于Semaphore所造成的當(dāng)前值怎樣
64、增加,都絕對(duì)不會(huì)超過CreateSemaphore時(shí)所指定的1MaximumCount。</p><p> 請(qǐng)記住,lpPreviousCount所傳回來的是一個(gè)瞬間值。你不可以把1ReleaseCount加上lpPreviousCount,就當(dāng)做是semaphore的當(dāng)前值,因?yàn)槠渌€程可能已經(jīng)改變了Semaphore的值。</p><p> 與mutex不同的是,調(diào)用Release
65、Semaphore的那個(gè)線程,并不一定就是調(diào)用WaitXxx的那個(gè)線程。仟何線程都可以在任何時(shí)間調(diào)用ReleaseSemaphore,解除被任何線程鎖定的Semaphore。</p><p> 10.InitializeCriticalSection</p><p><b> 函數(shù)功能:</b></p><p> 該函數(shù)初始化臨界區(qū)對(duì)象:
66、</p><p><b> 函數(shù)原型:</b></p><p> VOID InitializeCriticalSection (LPCRITIAL_SECTION lpCriticalSection);</p><p><b> 參數(shù):</b></p><p> ·lpCriti
67、alSection:指向臨界區(qū)對(duì)象的指針。</p><p><b> 備注:</b></p><p> 單進(jìn)程的所有線程可以使用互斥同步機(jī)制的臨界區(qū)對(duì)象。但是,不能保證線程獲得臨界區(qū)所有權(quán)的順序,系統(tǒng)將對(duì)所有線程公平處理。</p><p> 進(jìn)程負(fù)責(zé)分配臨界區(qū)對(duì)象使用的存儲(chǔ)空間,這可以通過聲明CRITICAL_SECTION類型的變量來完
68、成。在使用臨界區(qū)之前,該進(jìn)程的一些線程必須使用InitializeCriticalSection或InitializeCriticalSectionAndSpinCount函數(shù)來初始化該臨界區(qū)對(duì)象。</p><p> 11.EnterCriticalSection</p><p> 函數(shù)功能:該函數(shù)是等待指定臨界區(qū)對(duì)象的所有權(quán)。當(dāng)調(diào)用線程被賦予所有權(quán)時(shí),該函數(shù)返回。</p>
69、<p><b> 函數(shù)原型:</b></p><p> VOID EnterCriticalSection (LPCRITICAL_SECTION lpCriticalSecrion);</p><p><b> 參數(shù):</b></p><p> ·lpCriticalSecrion:指間臨
70、界區(qū)對(duì)象的指針。</p><p> 12.LeaveCriticalSection</p><p> 函數(shù)功能:該函數(shù)釋放指定臨界區(qū)對(duì)象的所有權(quán)。</p><p><b> 函數(shù)原型:</b></p><p> VOID LeaveCriticalSection (LPCRITICAL_SECTION lpCri
71、ticalSection);</p><p><b> 參數(shù);</b></p><p> ·lpCriticalSecrion:指向臨界區(qū)對(duì)象的指針。</p><p><b> 五、參考源代碼</b></p><p> 下面的程序已經(jīng)在Windows 2000上實(shí)現(xiàn)。用VC6.0創(chuàng)
72、建源文件,將輸入文件命名為thread.dat并放在與源文件相同的文件夾內(nèi),編譯運(yùn)行即可。</p><p> #include"windows.h"</p><p> #include<conio.h></p><p> #include<stdlib.h></p><p> #includ
73、e<fstream.h></p><p> #include<io.h></p><p> #include<string.h></p><p> #include<stdio.h></p><p> #define READER 'R'//讀者</p>
74、<p> #define WRITER 'W'//寫者</p><p> #define INTE_PER_SEC 1000//每秒時(shí)鐘中斷數(shù)目</p><p> #define MAX_THREAD_NUM 64//最大線程數(shù)目</p><p> #define MAX_FILE_NUM 32//最大數(shù)據(jù)文件數(shù)目
75、</p><p> #define MAX_STR__LEN 32//字符串長(zhǎng)度</p><p> int readcount=0;//讀者數(shù)目</p><p> int writecount=0;//寫者數(shù)目</p><p> CRITICAL_SECTION RP_Write;//臨界區(qū)</p>&
76、lt;p> CRITICAL_SECTION cs_Write;</p><p> CRITICAL_SECTION cs_Read;</p><p> struct ThreadInfo{</p><p> int serial;//線程序號(hào)</p><p> char entity;//線程類別(判斷是讀者線
77、程還是寫者線程)</p><p> double delay;//線程延遲</p><p> double persist;//線程寫操作持續(xù)時(shí)間</p><p><b> };</b></p><p> ////////////////////////////////////////////////
78、//</p><p> //讀者優(yōu)先——讀者線程</p><p> //P:讀者線程信息</p><p> void RP_ReaderThread(void *p)</p><p><b> {</b></p><p><b> //互斥變量</b></p&
79、gt;<p> HANDLE h_Mutex;</p><p> h_Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_redcount");</p><p> DWORD wait_for_mutex;//等待互斥變量所有權(quán)</p><p> DWORD m_delay
80、;//延遲時(shí)間</p><p> DWORD m_persist;//讀文件持續(xù)時(shí)間</p><p> int m_serial;//線程序號(hào)</p><p> //從參數(shù)中獲得信息</p><p> m_serial=((ThreadInfo*)(p))->serial;</p><p
81、> m_delay=(DWORD)(((ThreadInfo*)(p))->delay*INTE_PER_SEC);</p><p> m_persist=(DWORD)(((ThreadInfo*)(p))->persist*INTE_PER_SEC);</p><p> Sleep(m_delay);//延遲等待</p><p>
82、 printf("Reader thread %d sents the reading require.\n",m_serial);</p><p> //等待互斥信號(hào),保證對(duì)readcount的訪問、修改互斥</p><p> wait_for_mutex=WaitForSingleObject(h_Mutex,-1);</p><p>&
83、lt;b> //讀者數(shù)目增加</b></p><p> readcount++;</p><p> if(readcount==1)</p><p><b> {</b></p><p> //第一個(gè)讀者,等待資源</p><p> EnterCriticalSect
84、ion(&RP_Write);</p><p><b> }</b></p><p> ReleaseMutex(h_Mutex);//釋放互斥信號(hào)</p><p><b> //讀文件</b></p><p> printf("Reader thread %d begi
85、ns to read file.\n",m_serial);</p><p> Sleep(m_persist);</p><p><b> //退出線程</b></p><p> printf("Reader thread %d finished reading file.\n",m_serial);<
86、;/p><p> //等待互斥信號(hào),保證對(duì)readcount的訪問、修改互斥</p><p> wait_for_mutex=WaitForSingleObject(h_Mutex,-1);</p><p><b> //讀者數(shù)目減少</b></p><p> readcount--;</p><
87、p> if(readcount==0)</p><p><b> {</b></p><p> //如果所有的者讀完,喚醒寫者</p><p> LeaveCriticalSection(&RP_Write);</p><p><b> }</b></p>&l
88、t;p> ReleaseMutex(h_Mutex);//釋放互斥信號(hào)</p><p><b> }</b></p><p> //////////////////////////////////////////////////</p><p> //讀者優(yōu)先——寫者線程</p><p> //P:寫
89、者線程信息</p><p> void RP_WriterThread(void*p)</p><p><b> {</b></p><p> DWORD m_delay;//延遲時(shí)間</p><p> DWORD m_persist;//寫文件持續(xù)時(shí)間</p><p> in
90、t m_serial;//線程序號(hào)</p><p> //從參數(shù)中獲得信息</p><p> m_serial=((ThreadInfo*)(p))->serial;</p><p> m_delay=(DWORD)(((ThreadInfo*)(p))->delay*INTE_PER_SEC);</p><p>
91、m_persist=(DWORD)(((ThreadInfo*)(p))->persist*INTE_PER_SEC);</p><p> Sleep(m_delay);//延遲等待</p><p> printf("Writer thread %d sent the wrinting require.\n",m_serial);</p>
92、<p><b> //等待資源</b></p><p> EnterCriticalSection(&RP_Write);</p><p><b> //寫文件</b></p><p> printf("Writer thread %d begins to write to the fi
93、le.\n",m_serial);</p><p> Sleep(m_persist);</p><p><b> //退出線程</b></p><p> printf("Writer thread %d finishing writing to the file.\n",m_serial);</p&g
94、t;<p><b> //釋放資源</b></p><p> LeaveCriticalSection(&RP_Write);</p><p><b> }</b></p><p> //////////////////////////////////////////////////</
95、p><p> //讀者優(yōu)先處理函數(shù)</p><p> //file:文件名</p><p> void ReaderPriority(char *file)</p><p><b> {</b></p><p> DWORD n_thread=0;//線程數(shù)目</p>&l
96、t;p> DWORD thread_ID;//線程ID</p><p> DWORD wait_for_all;//等待所有線程結(jié)束</p><p><b> //互斥對(duì)象</b></p><p> HANDLE h_Mutex;</p><p> h_Mutex=CreateMutex(NULL
97、,FALSE,"mutex_for_readcount");</p><p><b> //線程對(duì)象的數(shù)組</b></p><p> HANDLE h_Thread[MAX_THREAD_NUM];</p><p> ThreadInfo thread_info[MAX_THREAD_NUM];</p>
98、<p> readcount=0;//初始化readcount</p><p> InitializeCriticalSection(&RP_Write);//初始化臨界區(qū)</p><p> ifstream inFile;</p><p> inFile.open(file);//打開文件</p>
99、<p> printf("Reader Priority:\n\n");</p><p> while(inFile)</p><p><b> {</b></p><p> //讀入每一個(gè)讀者、寫者的信息</p><p> inFile>>thread_info[n
100、_thread].serial;</p><p> inFile>>thread_info[n_thread].entity;</p><p> inFile>>thread_info[n_thread].delay;</p><p> inFile>>thread_info[n_thread++].persist;<
101、/p><p> inFile.get();</p><p><b> }</b></p><p> for(int i=0;i<(int)(n_thread);i++)</p><p><b> {</b></p><p> if(thread_info[i].e
102、ntity==READER || thread_info[i].entity=='r')</p><p><b> {</b></p><p><b> //創(chuàng)建讀者線程</b></p><p> h_Thread[i]=CreateThread(NULL,0,</p><p>
103、; (LPTHREAD_START_ROUTINE)(RP_ReaderThread),</p><p> &thread_info[i],</p><p> 0,&thread_ID);</p><p><b> }</b></p><p><b> else</b>&l
104、t;/p><p><b> //創(chuàng)建寫者線程</b></p><p> h_Thread[i]=CreateThread(NULL,0,</p><p> (LPTHREAD_START_ROUTINE)(RP_WriterThread),</p><p> &thread_info[i],</p>
105、;<p> 0,&thread_ID);</p><p><b> }</b></p><p> //等待所有線程結(jié)束</p><p> wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);</p><p> pri
106、ntf("All reader and writer have finished operating.\n");</p><p><b> }</b></p><p> /////////////////////////////////////////////////</p><p> //寫者優(yōu)先——讀者線程<
107、/p><p> //P:讀者線程信息</p><p> void WP_ReaderThread(void *p)</p><p><b> {</b></p><p> //請(qǐng)編寫寫者優(yōu)先的讀者線程</p><p> HANDLE h_Mutex1;h_Mutex1=OpenMutex(
108、MUTEX_ALL_ACCESS,FALSE,_T("mutex1"));HANDLE h_Mutex2;h_Mutex2=OpenMutex(MUTEX_ALL_ACCESS,FALSE,_T("mutex2"));DWORD wait_for_mutex1; //等待互斥變量所有權(quán)DWORD wait_for_mutex2;DWORD m_delay; //延遲時(shí)間DWORD
109、m_persist; //讀文件持續(xù)時(shí)間int m_serial; //線程的序號(hào)//從參數(shù)中得到信息m_serial=((ThreadInfo*)(p))->serial ; m_delay=(DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);m_persist=(DWORD)(((ThreadInfo*)(p))->persist *INTE_PER_SEC
110、);Sleep(m_delay); //延遲等待printf("Reader thread %d </p><p><b> }</b></p><p> //////////////////////////////////////////////</p><p> //寫者優(yōu)先——寫者線程</p><
111、;p> //P:寫者線程信息</p><p> void WP_WriterThread(void*p)</p><p><b> {</b></p><p> //請(qǐng)編寫寫者優(yōu)先的寫者線程</p><p> DWORD wait_for_mutex3; //互斥變量DWORD m_delay; //延
112、遲時(shí)間DWORD m_persist; //讀文件持續(xù)時(shí)間int m_serial; //線程序號(hào)HANDLE h_Mutex3;h_Mutex3=OpenMutex(MUTEX_ALL_ACCESS,FALSE,_T("mutex3"));//從參數(shù)中獲得信息m_serial=((ThreadInfo*)(p))->serial ;m_delay=(DWORD)(((ThreadInfo*
113、)(p))->delay *INTE_PER_SEC);m_persist=(DWORD)(((ThreadInfo*)(p))->persist *INTE_PER_SEC);Sleep(m_delay); //延遲等待printf("Writer thread %d sents the writing require.\n",m_serial);wait_for_mutex3=WaitFo
114、rSingleObject(h_Mutex3,-1);writecount++;</p><p><b> }</b></p><p> ////////////////////////////////////////////////</p><p> //寫者優(yōu)先處理函數(shù)</p><p> //file:文件
115、名</p><p> void WriterPriority(char *file)</p><p><b> {</b></p><p> //請(qǐng)編寫寫者優(yōu)先處理函數(shù)</p><p> DWORD n_thread=0;DWORD thread_ID;DWORD wait_for_all;HANDLE
116、 h_Mutex1;h_Mutex1=CreateMutex(NULL,FALSE,_T("mutex1"));HANDLE h_Mutex2;h_Mutex2=CreateMutex(NULL,FALSE,_T("mutex2"));HANDLE h_Mutex3;h_Mutex3=CreateMutex(NULL,FALSE,_T("mutex3"));HAND
117、LE h_Thread[MAX_THREAD_NUM];ThreadInfo thread_info[MAX_THREAD_NUM];readcount=0;writecount=0;InitializeCriticalSection(&cs_Write);InitializeCriticalSection(&cs_Read);ifstream inFile;inFile.open (file);p
118、rintf("Writer priority:\n\n");whil</p><p><b> }</b></p><p> ///////////////////////////////////////////////////</p><p><b> //主函數(shù)</b></p>
119、<p> int main(int argc,char *argv[])</p><p><b> {</b></p><p><b> char ch;</b></p><p> while(true)</p><p><b> {</b></p&
120、gt;<p><b> //打印提示信息</b></p><p> printf("*********************************************\n");</p><p> printf(" 1:Reader Priority\n");</p>&l
121、t;p> printf(" 2:Writer Priority\n");</p><p> printf(" 3:Exit to Windows\n");</p><p> printf("*********************************************\n")
122、;</p><p> printf("Enter your choice(1,2or3):");</p><p> //如果輸入信息不正確,繼續(xù)輸入</p><p><b> do{</b></p><p> ch=(char)_getch();</p><p> }
溫馨提示
- 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 操作系統(tǒng)課程設(shè)計(jì)-讀者寫者問題
- 操作系統(tǒng)課程設(shè)計(jì)——讀者寫者問題
- 操作系統(tǒng)課程設(shè)計(jì)---讀者-寫者問題實(shí)現(xiàn)
- 操作系統(tǒng)原理課程設(shè)計(jì)讀者-寫者問題的實(shí)現(xiàn)
- 操作系統(tǒng)課程設(shè)計(jì)-- linux下讀者與寫者的問題實(shí)現(xiàn)
- 讀者與寫者-操作系統(tǒng)課程設(shè)計(jì)實(shí)驗(yàn)報(bào)告
- 讀者寫者問題-操作系統(tǒng)實(shí)驗(yàn)報(bào)告
- 操作系統(tǒng)課程設(shè)計(jì)報(bào)告-讀者寫著問題
- 北理工操作系統(tǒng)實(shí)驗(yàn)二讀者寫者問題
- 讀者寫者課程設(shè)計(jì)
- 讀者與寫者問題課程設(shè)計(jì)報(bào)告
- 《操作系統(tǒng)》課程設(shè)計(jì)--基于信號(hào)量與pv操作同步機(jī)制的讀者寫者問題的設(shè)計(jì)與實(shí)現(xiàn)
- 操作系統(tǒng)課程設(shè)計(jì)——操作系統(tǒng)課程設(shè)計(jì)模擬操作系統(tǒng)
- 操作系統(tǒng)課程設(shè)計(jì)——生產(chǎn)者消費(fèi)者問題
- 操作系統(tǒng)課程設(shè)計(jì)——生產(chǎn)者消費(fèi)者問題
- 生產(chǎn)者消費(fèi)者問題操作系統(tǒng)課程設(shè)計(jì)
- 操作系統(tǒng)課程設(shè)計(jì)-- 操作系統(tǒng)
- 操作系統(tǒng)課程設(shè)計(jì)實(shí)現(xiàn)生產(chǎn)者消費(fèi)者問題
- 操作系統(tǒng)課程設(shè)計(jì)--蘋果問題
- 操作系統(tǒng)課程設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論