版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
本文格式為Word版,下載可任意編輯——操作系統(tǒng)試驗教案1(打印版)
《操作系統(tǒng)原理》
實驗教案
(基于Windows2000/XP平臺)
講授人:謝士春
安排授課時間:2023-2023(一)授課對象:09計算機科學(xué)與技術(shù)
試驗項目列表
試驗一多線程的創(chuàng)立與撤銷試驗二線程的同步試驗三線程的互斥試驗四生產(chǎn)者-消費者問題試驗五進程通信
試驗六動態(tài)鏈接庫的建立和調(diào)試試驗七頁面置換算法模擬
試驗八文件的三種傳輸模式及性能比較試驗九磁盤的讀寫
附錄部分(可擴展)
附錄1讀者-寫者問題附錄2梨子蘋果之PV操作附錄3命名管道編程規(guī)范附錄4DLL編程規(guī)范
II頁第
試驗一線程的創(chuàng)立與撤銷
一、試驗?zāi)康?/p>
通過本試驗熟悉Windows系統(tǒng)提供的線程創(chuàng)立與撤銷等API系統(tǒng)調(diào)用,把握Windows系統(tǒng)環(huán)境下線程的創(chuàng)立與撤銷方法。
二、試驗內(nèi)容
1.熟悉開發(fā)環(huán)境VisualC++6.0;
2.Windows系統(tǒng)環(huán)境下線程的創(chuàng)立與撤銷方法;
3.編程:在主線程中調(diào)用CreateThread()創(chuàng)立1個子線程,并在子線程中顯示類似“Threadisrunning!〞等字樣。
三、試驗準(zhǔn)備知識
相關(guān)的API函數(shù)的函數(shù)原型:
1.線程創(chuàng)立函數(shù)HANDLECreateThread();HANDLECreateThread(
LPSECURITY_ATTRIBUTESlpThreadAttributes,//pointertosecurityattributesDWORDdwStackSize,//initialthreadstacksizeLPTHREAD_START_ROUTINElpStartAddress,//pointertothreadfunctionLPVOIDlpParameter,//argumentfornewthreadDWORDdwCreationFlags,//creationflags
LPDWORDlpThreadId//pointertoreceivethreadID);
線程函數(shù)原型DWORDWINAPIThread1Proc(LPVOIDlpParameter)2.線程撤銷函數(shù)VOIDExitThread(
DWORDdwExitCode//exitcodeforthisthread);
功能:撤銷一個線程。該函數(shù)將終止線程的運行,并導(dǎo)致操作系統(tǒng)清除該線程使用的所有操作系統(tǒng)資源。但是,C++資源(如C++類對象)將不被撤消。
說明:假使在主線程函數(shù)(main函數(shù))中調(diào)用ExitThread,那么應(yīng)用程序的主線程將中止運行。但是,假使進程中至少有一個線程還在運行,該進程將不會終止運行。3.線程終止函數(shù)TerminateThread();
4.線程掛起函數(shù)Sleep();進程主動放棄剩余的時間片。5.關(guān)閉句柄函數(shù)CloseHandle()。
說明:關(guān)閉一個對象句柄,只是將相應(yīng)對象的引用數(shù)減一,并不意味著終結(jié)該對象,除非引用數(shù)減至零。
四、程序源代碼及解釋
#include#include
staticHANDLEhThread1=NULL;//存放創(chuàng)立的子進程的句柄DWORDdwThreadID1;//存放創(chuàng)立的子進程的IDDWORDWINAPIThread1Proc(LPVOID);//子線程函數(shù)的聲明
1頁第
intmain()//主線程{//創(chuàng)立子線程
hThread1=CreateThread(NULL,0,Thread1Proc,
NULL,0,
Sleep(5000);
CloseHandle(hThread1);//關(guān)閉句柄ExitThread(0);//撤銷本線程return0;}
//子線程的實現(xiàn)
DWORDWINAPIThread1Proc(LPVOIDlpParameter){
coutLPCTSTRlpName//pointertosemaphore-objectname);
功能:創(chuàng)立一個信號量。舉例:
hHandle1=CreateSemaphore(NULL,0,5,〞Semaphore1〞);
HANDLEOpenSemaphore(
DWORDdwDesiredAccess,//accessflagBOOLbInheritHandle,//inheritflag
LPCTSTRlpName//pointertosemaphore-objectname);
功能:開啟一個已存在的信號量。舉例:
hHandle2=OpenSemaphore(SEMAPHORE_MODIFY_STATE|SYNCHRONIZE,NULL,\
BOOLReleaseSemaphore(
HANDLEhSemaphore,//handletothesemaphoreobjectLONGlReleaseCount,//amounttoaddtocurrentcountLPLONGlpPreviousCount//addressofpreviouscount);
功能:對指定的信號量對象增值。舉例:
rc=ReleaseSemaphore(hHandle1,1,NULL);
四、程序源代碼及解釋
//定義全局變量,諸線程均可訪問
staticHANDLEhThread1;//子進程的句柄,作為主線程的局部變量也行staticHANDLEhHandle1=NULL;//信號量的句柄,全局變量voidfunc();//子線程的聲明
int_tmain(intargc,TCHAR*argv[],TCHAR*envp[]){
intnRetCode=0;
DWORDdwThreadID1;DWORDdRes,err;
hHandle1=CreateSemaphore(NULL,0,1,\創(chuàng)立一個信號量if(hHandle1==NULL)printf(\elseprintf(\
hHandle1=OpenSemaphore(SYNCHRONIZE|SEMAPHORE_MODIFY_STATE,NULL,\emaphoreName1\
if(hHandle1==NULL)printf(\elseprintf(\
hThread1=CreateThread((LPSECURITY_ATTRIBUTES)NULL,0,(LPTHREAD_START_ROUTINE)func,(LPVOID)NULL,
4頁第
0,//創(chuàng)立子線程
if(hThread1==NULL)printf(\elseprintf(\
dRes=WaitForSingleObject(hHandle1,INFINITE);//主線程等待子線程終止err=GetLastError();
printf(\
if(dRes==WAIT_TIMEOUT)
printf(\elseif(dRes==WAIT_OBJECT_0)
printf(\elseif(dRes==WAIT_ABANDONED)
printf(\elseprintf(\
CloseHandle(hThread1);CloseHandle(hHandle1);ExitThread(0);
returnnRetCode;}
//實現(xiàn)子線程voidfunc(){
BOOLrc;DWORDerr;
printf(\
rc=ReleaseSemaphore(hHandle1,1,NULL);//子線程喚醒主線程err=GetLastError();
printf(\
if(rc==0)printf(\
elseprintf(\}
五、試驗結(jié)果輸出
5頁第
試驗三線程的互斥
一、試驗任務(wù)
完成兩個子線程之間的互斥。在主線程中使用系統(tǒng)調(diào)用CreateThread()創(chuàng)立兩個子線程,并使兩個子線程互斥的使用全局變量count。
二、試驗?zāi)康?/p>
1.熟練把握Windows系統(tǒng)環(huán)境下線程的創(chuàng)立與撤銷。2.熟悉Windows系統(tǒng)提供的線程互斥API。
3.使用Windows系統(tǒng)提供的線程互斥API解決實際問題。
三、試驗準(zhǔn)備知識
1.使用臨界區(qū)對象(Criticalsection)
CriticalSectionObject,Asegmentofcodethatisnotreentrantandthereforedoesnotsupportconcurrentaccessbymultiplethreads.Often,acriticalsectionobjectisusedtoprotectsharedresources。通過定義在數(shù)據(jù)段中的一個CRITICAL_SECTION結(jié)構(gòu)實現(xiàn)。CRITICAL_SECTIONmyCritical;
并且在任何線程使用此臨界區(qū)對象之前必需對它進行初始化。
voidInitializeCriticalSection(LPCRITICAL_SECTIONlpCriticalSection);
之后,任何線程訪問臨界區(qū)中數(shù)據(jù)的時候,必需首先調(diào)用EnterCriticalSection函數(shù),申請進入臨界區(qū)(又叫關(guān)鍵代碼段,使用共享資源的任何代碼都必需封裝在此)。在同一時間內(nèi),Windows只允許一個線程進入臨界區(qū)。所以在申請的時候,假使有另一個線程在臨界區(qū)的話,EnterCriticalSection函數(shù)會一直等待下去,直到其他線程離開臨界區(qū)才返回。EnterCriticalSection函數(shù)用法如下:
voidEnterCriticalSection(LPCRITICAL_SECTIONlpCriticalSection);
當(dāng)操作完成的時候,還要將臨界區(qū)交還給Windows,以便其他線程可以申請使用。這個工作由LeaveCriticalSection函數(shù)來完成。
voidLeaveCriticalSection(LPCRITICAL_SECTIONlpCriticalSection);
當(dāng)程序不再使用臨界區(qū)對象的時候,必需使用DeleteCriticalSection函數(shù)將它刪除。voidDeleteCriticalSection(LPCRITICAL_SECTIONlpCriticalSection);2.使用互斥鎖(Interlocked)
提供一種手段來保證值的遞增(減)能夠以原子操作方式來進行,也就是不中斷地進行。LONGInterlockedIncrement(LPLONGlpAddend);//增一操作LONGInterlockedDecrement(LPLONGlpAddend);//減一操作LONGInterlockedExchangeAdd(
PLONGAddend,//pointertotheaddendLONGIncrement//incrementvalue);//增減任意值
四、程序源代碼及解釋
這里以使用臨界區(qū)對象為例
staticintcount=5;//共享變量
staticHANDLEh1,h2;//兩個子進程的句柄變量
LPCRITICAL_SECTIONhCriticalSection;//定義指向臨界區(qū)對象的地址指針CRITICAL_SECTIONCritical;//定義臨界區(qū)
6頁第
voidfunc1()//線程函數(shù)的定義不符合WIN32格式,后面CreateThread函數(shù)中voidfunc2()//要附加強制類型轉(zhuǎn)換
//主線程的實現(xiàn)
int_tmain(intargc,TCHAR*argv[],TCHAR*envp[]){
intnRetCode=0;
DWORDdwThreadID1,dwThreadID2;
hCriticalSection=//將指向臨界區(qū)的對象的指針指向臨界區(qū)InitializeCriticalSection(hCriticalSection);//初始化臨界區(qū)//創(chuàng)立子線程func1
h1=CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)func1,
(LPVOID)NULL,0,
if(h1==NULL)printf(\elseprintf(\
//創(chuàng)立子線程func2
h2=CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)func2,
(LPVOID)NULL,
0,
if(h2==NULL)printf(\elseprintf(\
Sleep(1000);
CloseHandle(h1);CloseHandle(h2);
DeleteCriticalSection(hCriticalSection);//刪除臨界區(qū)ExitThread(0);returnnRetCode;}//主線程終止
//子線程func2的實現(xiàn)voidfunc2(){intr2;
EnterCriticalSection(hCriticalSection);//進入臨界區(qū)r2=count;Sleep(100);r2=r2+1;
7頁第
count=r2;
printf(\
LeaveCriticalSection(hCriticalSection);//退出臨界區(qū)}
//子線程func1的實現(xiàn)voidfunc1(){intr1;
EnterCriticalSection(hCriticalSection);//進入臨界區(qū)r1=count;
Sleep(500);r1=r1+1;count=r1;
printf(\
LeaveCriticalSection(hCriticalSection);//退出臨界區(qū)}
五、試驗結(jié)果輸出參考
8頁第
試驗四生產(chǎn)者消費者問題
一、試驗任務(wù)
1.在WINDOWS2000環(huán)境下,創(chuàng)立一個控制臺進程,此進程包括多個生產(chǎn)者線程和多個消費者線程。
2.用信號量機制解決進程(線程)的同步與互斥問題。
二、試驗?zāi)康?/p>
1.把握基本的同步互斥算法,理解生產(chǎn)者和消費者模型。
2.了解Windows2000/XP中多線程的并發(fā)執(zhí)行機制,線程間的同步和互斥。3.學(xué)習(xí)使用Windows2000/XP中基本的同步對象,把握相應(yīng)的API函數(shù)。
三、試驗要求
1.生產(chǎn)者消費者對緩沖區(qū)進行互斥操作。
2.緩沖區(qū)大小為10,緩沖區(qū)滿則不允許生產(chǎn)者生產(chǎn)數(shù)據(jù),緩沖區(qū)空則不允許消費者消費數(shù)據(jù)。
3.生產(chǎn)者消費者循環(huán)操作可隨時終止。
四、試驗準(zhǔn)備知識
1.互斥量對象(mutex)
互斥對象能夠確保線程擁有對單個資源的互斥訪問權(quán)?;コ鈱ο蟀粋€引用數(shù)量,一個線程ID和一個遞歸計數(shù)器?;コ鈱ο蟮氖褂靡?guī)則如下:
?假使線程ID是0(這是個無效ID),互斥對象不被任何線程所擁有,互斥對象處于“受信〞狀態(tài)。
?假使ID是個非0數(shù)字,那么一個線程就擁有互斥對象,互斥對象處于“未受信〞狀態(tài)。
函數(shù)原型
HANDLECreateMutex(
LPSECURITY_ATTRIBUTESlpMutexAttributes,//pointertosecurityattributes
BOOLbInitialOwner,//flagforinitialownership
LPCTSTRlpName//pointertomutex-objectname);
作用:創(chuàng)立一個命名或無名互斥對象。舉例:
hHandle=CreateMutex(NULL,false,NULL);
//創(chuàng)立一個無名互斥對象,放棄擁有權(quán)(ownership),此時互斥量處于“受信〞狀態(tài)。
HANDLEOpenMutex(
DWORDdwDesiredAccess,//accessflagBOOLbInheritHandle,//inheritflag
LPCTSTRlpName//pointertomutex-objectname);
作用:開啟一個命名的互斥對象。
BOOLReleaseMutex(
HANDLEhMutex//handletomutexobject
9頁第
);
作用:釋放一個互斥對象,該函數(shù)同時將對象的遞歸計數(shù)器遞減1。當(dāng)遞歸計數(shù)器到達(dá)0時,該線程ID也被置為0,同時該對象變?yōu)椤笆苄浓暊顟B(tài)。
說明:不同于其他內(nèi)核對象,互斥對象有一個“線程所有權(quán)〞的概念。當(dāng)一個線程調(diào)用ReleaseMutex函數(shù)釋放互斥對象時,該函數(shù)要查看調(diào)用線程的ID是否與互斥對象中的線程ID相匹配。假使兩個ID相匹配,遞歸計數(shù)器就會遞減;假使兩個線程的ID不匹配,那么ReleaseMutex函數(shù)將不進行任何操作,而是將FALSE(表示失敗)返回給調(diào)用者。
2.事件對象
事件對象能夠通知一個操作已經(jīng)完成。在所有的內(nèi)核對象中,事件內(nèi)核對象是個最基本的對象。它們包含一個使用計數(shù),一個用于指明該事件是個自動重置的事件還是一個人工重置的事件的布爾值,另一個用于指明該事件處于“受信〞狀態(tài)還是“未受信〞狀態(tài)的布爾值。
函數(shù)原型
HANDLECreateEvent(
LPSECURITY_ATTRIBUTESlpEventAttributes,
//pointertosecurityattributesBOOLbManualReset,//flagformanual-reseteventBOOLbInitialState,//flagforinitialstate
LPCTSTRlpName//pointertoevent-objectname);
作用:創(chuàng)立一個事件對象。
說明:有兩種不同類型的事件對象。一種是人工重置的事件,另一種是自動重置的事件。
HANDLEOpenEvent(
DWORDdwDesiredAccess,//accessflagBOOLbInheritHandle,//inheritflag
LPCTSTRlpName//pointertoevent-objectname);
作用:開啟一個事件對象。
BOOLSetEvent(
HANDLEhEvent//handletoeventobject);
作用:將事件對象設(shè)置為“受信〞狀態(tài)。說明:當(dāng)人工重置的事件為“受信〞時,等待該事件的所有線程均變?yōu)榭烧{(diào)度線程;當(dāng)一個自動重置的事件為“受信〞時,等待該事件的線程中只有一個線程變?yōu)榭烧{(diào)度線程。
BOOLResetEvent(
HANDLEhEvent//handletoeventobject);
作用:將事件對象設(shè)置為“未受信〞狀態(tài)。
說明:Microsoft為自動重置的事件定義了應(yīng)當(dāng)成功等待的副作用規(guī)則,即當(dāng)線程成功地等待到該對象時,自動重置的事件就會自動重置到“未受信〞狀態(tài)。尋常沒有必要為自動重置的事件調(diào)用ResetEvent函數(shù),由于系統(tǒng)會自動對事件進行重置。但是,Microsoft沒有為人工重置的事件定義成功等待的副作用,即線程必需使用ResetEvent才能使得重置到“未受信〞狀態(tài)。
五、程序源代碼及解釋
10頁第
#include
#ifdef_DEBUG
#definenewDEBUG_NEW#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;#endif
///////////////////////////////////////////////////////////////////////////////TheoneandonlyapplicationobjectCWinApptheApp;
usingnamespacestd;
constunsignedshortSIZE_OF_BUFFER=10;//緩沖區(qū)長度
unsignedshortProductID=0;//這里的產(chǎn)品號和將被消耗的產(chǎn)品號是
unsignedshortConsumeID=0;//為了跟蹤產(chǎn)品的存取過程而引入的輔助變量
unsignedshortin=0;//緩沖區(qū)下標(biāo),指向生產(chǎn)者要放產(chǎn)品的緩沖區(qū)單元unsignedshortout=0;//緩沖區(qū)下標(biāo),指向消費者要取產(chǎn)品的緩沖區(qū)單元intg_buffer[SIZE_OF_BUFFER];//緩沖區(qū)是個循環(huán)隊列boolg_continue=true;//總控開關(guān),可隨時終止諸進程
HANDLEg_hMutex;//互斥信號量句柄,用于諸線程互斥訪問緩沖區(qū)
HANDLEg_hFullSemaphore;//資源信號量句柄,代表緩沖區(qū)內(nèi)已放置的產(chǎn)品數(shù)HANDLEg_hEmptySemaphore;//資源信號量句柄,代表緩沖區(qū)內(nèi)空閑的單元數(shù)
DWORDWINAPIProducer(LPVOID);//生產(chǎn)者線程聲明DWORDWINAPIConsumer(LPVOID);//消費者線程聲明int_tmain(intargc,TCHAR*argv[],TCHAR*envp[]){intnRetCode=0;
g_hMutex=CreateMutex(NULL,FALSE,NULL);//互斥信號量g_hFullSemaphore=CreateSemaphore(
NULL,
0,//初始緩沖區(qū)內(nèi)無產(chǎn)品
SIZE_OF_BUFFER-1,NULL);
g_hEmptySemaphore=CreateSemaphore(
NULL,
SIZE_OF_BUFFER-1,//初始均是空緩沖區(qū)SIZE_OF_BUFFER-1,NULL);
//調(diào)整下面的數(shù)值,可以發(fā)現(xiàn),當(dāng)生產(chǎn)者個數(shù)多于消費者個數(shù)時,//生產(chǎn)速度快,生產(chǎn)者經(jīng)常等待消費者;反之,消費者經(jīng)常等待
constunsignedshortPRODUCERS_COUNT=3;//生產(chǎn)者的個數(shù)constunsignedshortCONSUMERS_COUNT=1;//消費者的個數(shù)constunsignedshortTHREADS_COUNT=
PRODUCERS_COUNT+CONSUMERS_COUNT;//總的線程數(shù)
HANDLEhThreads[THREADS_COUNT];//諸線程的handle表
11頁第
DWORDproducerID[CONSUMERS_COUNT];//生產(chǎn)者線程的標(biāo)識符表DWORDconsumerID[PRODUCERS_COUNT];//消費者線程的標(biāo)識符表
//創(chuàng)立生產(chǎn)者諸線程
for(inti=0;i
}
{err=GetLastError();
printf(\elseprintf(\
DisconnectNamedPipe(hPipeHandle);//拆除與管道命令連接rc=strcmp(OutBuffer,\if(rc==0)break;
printf(\CloseHandle(hPipeHandle);
returnnRetCode;}
/***********客戶端進程***********/#include\#include\#ifdef_DEBUG
#definenewDEBUG_NEW#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;#endif
///////////////////////////////////////////////////////////////////////////////TheoneandonlyapplicationobjectCWinApptheApp;usingnamespacestd;
int_tmain(intargc,TCHAR*argv[],TCHAR*en
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 外匯預(yù)收貨款合同范例
- 種牛租賃合同范例
- 鄉(xiāng)村居民個人借款合同范例
- 二手轉(zhuǎn)讓房屋買賣合同范例
- 正規(guī)送貨合同范例
- 聘請兼職律師合同范例
- 吹填砂合同范例
- 注冊地址合同范例
- 公司領(lǐng)導(dǎo)承攬工程合同范例
- 聘用司機勞務(wù)合同范例
- 三級醫(yī)院醫(yī)療設(shè)備配置標(biāo)準(zhǔn)
- 合法離婚協(xié)議書(2篇)
- 水輪發(fā)電機組大修質(zhì)量標(biāo)準(zhǔn)
- 項目主要技術(shù)方案計劃表
- 汽車零部件開發(fā)質(zhì)量管理課件
- 20m29.6m30.4m20m鋼箱梁橋?qū)嵗O(shè)計內(nèi)容與表達(dá)
- 冀教版四年級上冊英語Unit 4單元測試卷(含聽力音頻)
- 【真題】北京市西城區(qū)六年級語文第一學(xué)期期末試卷 2021-2022學(xué)年(有答案)
- VMWare Horizon7平臺集成指南
- 口腔??谱o理知識考核試題與答案
- 音響工作總結(jié)共3篇(劇院音響工作個人總結(jié))
評論
0/150
提交評論