




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
操作系統(tǒng)實(shí)驗(yàn)報(bào)告課程名稱操作系統(tǒng)實(shí)驗(yàn)課程編號0906553實(shí)驗(yàn)項(xiàng)目名稱進(jìn)程的同步學(xué)號年級姓名專業(yè)學(xué)生所在學(xué)院指導(dǎo)教師實(shí)驗(yàn)室名稱地點(diǎn)哈爾濱工程大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院
第五講進(jìn)程的同步一、實(shí)驗(yàn)概述1.實(shí)驗(yàn)名稱進(jìn)程的同步2.實(shí)驗(yàn)?zāi)康氖褂肊OS的信號量,編程解決生產(chǎn)者消費(fèi)者問題,理解進(jìn)程同步的意義。調(diào)試跟蹤EOS信號量的工作過程,理解進(jìn)程同步的原理。修改EOS的信號量算法,使之支持等待超時(shí)喚醒功能(有限等待),加深理解進(jìn)程同步的原理。3.實(shí)驗(yàn)類型驗(yàn)證,設(shè)計(jì)4.實(shí)驗(yàn)內(nèi)容4.1準(zhǔn)備實(shí)驗(yàn)4.2使用EOS的信號量解決生產(chǎn)者-消費(fèi)者問題4.3調(diào)試EOS信號量的工作過程4.3.1創(chuàng)建信號量4.3.2等待、釋放信號量4.3.2.1等待信號量(不阻塞)4.3.2.2釋放信號量(不喚醒)4.3.2.3等待信號量(阻塞)4.3.2.4釋放信號量(喚醒)4.4修改EOS的信號量算法二、實(shí)驗(yàn)環(huán)境操作系統(tǒng)集成實(shí)驗(yàn)環(huán)境OSLabEOS操作系統(tǒng)三、實(shí)驗(yàn)過程1.設(shè)計(jì)思路和流程圖2.需要解決的問題及解答(1).P143生產(chǎn)者在生產(chǎn)了13號產(chǎn)品后本來要繼續(xù)生產(chǎn)14號產(chǎn)品,可此時(shí)生產(chǎn)者為什么必須等待消費(fèi)者消費(fèi)了4號產(chǎn)品后,才能生產(chǎn)14號產(chǎn)品呢?生產(chǎn)者和消費(fèi)者是怎樣使用同步對象來實(shí)現(xiàn)該同步過程的呢?答:此時(shí)生產(chǎn)了0-13號14個(gè)產(chǎn)品,消費(fèi)了0-3號4個(gè)產(chǎn)品,緩沖區(qū)都占滿了。只有緩沖區(qū)有空閑生產(chǎn)者才能生產(chǎn)東西,有權(quán)向里面放東西。所以它必須等到消費(fèi)者,取走產(chǎn)品,有空閑緩沖區(qū)時(shí),才繼續(xù)生產(chǎn)14號產(chǎn)品。(2).P145-3.4修改EOS的信號量算法(只看一次消費(fèi)1個(gè)產(chǎn)品的,一次消費(fèi)2個(gè)產(chǎn)品的可以寫到實(shí)驗(yàn)報(bào)告中)答:見之后部分(3).思考在ps/semaphore.c文件內(nèi)的PsWaitForSemaphore和PsReleaseSemaphore函數(shù)中,為什么要使用原子操作?答:原子操作要求一旦開始就要運(yùn)行到結(jié)束,不能有中斷。在執(zhí)行等待信號量和釋放信號量的時(shí)候,不允許cpu響應(yīng)外部中斷,所以使用原子操作。(4).繪制ps/semaphore.c文件內(nèi)PsWaitForSemaphore和PsReleaseSemaphore函數(shù)的流程圖。原子操作前關(guān)中斷PsWaitForSemaphore原子操作前關(guān)中斷開始原子操作P開始原子操作P操作Wait操作的信號量大于0Wait操作的信號量大于0N執(zhí)行P執(zhí)行P操作YP操作結(jié)束P操作結(jié)束PsReleaseSemaphore原子操作前關(guān)中斷原子操作前關(guān)中斷開始原子操作開始原子操作V操作NP和NP和V操作的信號量之和大于緩沖隊(duì)列長度Y記錄當(dāng)前信號量的值Y記錄當(dāng)前信號量的值返回“信號數(shù)目量超出范圍”釋放信號量返回“信號數(shù)目量超出范圍”釋放信號量信號量值+1信號量值+1NPNP操作控制的信號量不大于0N被阻塞進(jìn)程量小于要釋放的信號量YN被阻塞進(jìn)程量小于要釋放的信號量Y喚醒等待進(jìn)程喚醒等待進(jìn)程YY喚醒隊(duì)列中進(jìn)程喚醒隊(duì)列中進(jìn)程N(yùn)N等待隊(duì)等待隊(duì)列為空YY返回“喚醒成功”返回“喚醒成功”結(jié)束結(jié)束3.主要數(shù)據(jù)結(jié)構(gòu)、實(shí)現(xiàn)代碼及其說明ps/semaphore.c文件#include"psp.h"VOIDPsInitializeSemaphore( INPSEMAPHORESemaphore, INLONGInitialCount, INLONGMaximumCount)/*++功能描述: 初始化信號量結(jié)構(gòu)體。參數(shù): Semaphore--要初始化的信號量結(jié)構(gòu)體指針。 InitialCount--信號量的初始值,不能小于0且不能大于MaximumCount。 MaximumCount--信號量的最大值,必須大于0。返回值:無。--*/{ ASSERT(InitialCount>=0&&InitialCount<=MaximumCount&&MaximumCount>0);Semaphore->Count=InitialCount; Semaphore->MaximumCount=MaximumCount; ListInitializeHead(&Semaphore->WaitListHead);}STATUSPsWaitForSemaphore( INPSEMAPHORESemaphore, INULONGMilliseconds)/*++功能描述: 信號量的Wait操作(P操作)。參數(shù): Semaphore--Wait操作的信號量對象。 Milliseconds--等待超時(shí)上限,單位毫秒。返回值: STATUS_SUCCESS。 當(dāng)你修改信號量使之支持超時(shí)喚醒功能后,如果等待超時(shí),應(yīng)該返回STATUS_TIMEOUT。--*/{ BOOLIntState; STATUSflag; ASSERT(KeGetIntNesting()==0);//中斷環(huán)境下不能調(diào)用此函數(shù)。IntState=KeEnableInterrupts(FALSE);//開始原子操作,禁止中斷。 //目前僅實(shí)現(xiàn)了標(biāo)準(zhǔn)記錄型信號量,不支持超時(shí)喚醒功能,所以PspWait函數(shù) //的第二個(gè)參數(shù)的值只能是INFINITE。 if(Semaphore->Count>0){ Semaphore->Count--; flag=STATUS_SUCCESS; } else flag=PspWait(&Semaphore->WaitListHead,Milliseconds);KeEnableInterrupts(IntState);//原子操作完成,恢復(fù)中斷。returnflag;}STATUSPsReleaseSemaphore( INPSEMAPHORESemaphore, INLONGReleaseCount, OUTPLONGPreviousCount ){ STATUSStatus; BOOLIntState;IntState=KeEnableInterrupts(FALSE);//開始原子操作,禁止中斷。if(Semaphore->Count+ReleaseCount>Semaphore->MaximumCount){Status=STATUS_SEMAPHORE_LIMIT_EXCEEDED;}else{//記錄當(dāng)前的信號量的值。 if(NULL!=PreviousCount){ *PreviousCount=Semaphore->Count; } intmm=Semaphore->Count;//目前僅實(shí)現(xiàn)了標(biāo)準(zhǔn)記錄型信號量,每執(zhí)行一次信號量的釋放操作 //只能使信號量的值增加1。 while((!ListIsEmpty(&Semaphore->WaitListHead))&&(ReleaseCount)){ PspWakeThread(&Semaphore->WaitListHead,STATUS_SUCCESS); PspThreadSchedule(); ReleaseCount--; } Semaphore->Count=mm+ReleaseCount;//可能有線程被喚醒,執(zhí)行線程調(diào)度。 Status=STATUS_SUCCESS; }KeEnableInterrupts(IntState);//原子操作完成,恢復(fù)中斷。returnStatus;}POBJECT_TYPEPspSemaphoreType=NULL;//用于初始化semaphore結(jié)構(gòu)體的參數(shù)結(jié)構(gòu)體。typedefstruct_SEM_CREATE_PARAM{ LONGInitialCount; LONGMaximumCount;}SEM_CREATE_PARAM,*PSEM_CREATE_PARAM;//semaphore對象的構(gòu)造函數(shù),在創(chuàng)建新semaphore對象時(shí)被調(diào)用。VOIDPspOnCreateSemaphoreObject( INPVOIDSemaphoreObject, INULONG_PTRCreateParam){ PsInitializeSemaphore((PSEMAPHORE)SemaphoreObject, ((PSEM_CREATE_PARAM)CreateParam)->InitialCount, ((PSEM_CREATE_PARAM)CreateParam)->MaximumCount);}//semaphore對象類型的初始化函數(shù)。VOIDPspCreateSemaphoreObjectType( VOID){ STATUSStatus; OBJECT_TYPE_INITIALIZERInitializer; Initializer.Create=PspOnCreateSemaphoreObject; Initializer.Delete=NULL; Initializer.Wait=(OB_WAIT_METHOD)PsWaitForSemaphore; Initializer.Read=NULL; Initializer.Write=NULL; Status=ObCreateObjectType("SEMAPHORE",&Initializer,&PspSemaphoreType); if(!EOS_SUCCESS(Status)){ KeBugCheck("Failedtocreatesemaphoreobjecttype!"); }}//semaphore對象的構(gòu)造函數(shù)。STATUSPsCreateSemaphoreObject( INLONGInitialCount, INLONGMaximumCount, INPSTRName, OUTPHANDLESemaphoreHandle ){ STATUSStatus; PVOIDSemaphoreObject; SEM_CREATE_PARAMCreateParam; if(InitialCount<0||MaximumCount<=0||InitialCount>MaximumCount){ returnSTATUS_INVALID_PARAMETER; }//創(chuàng)建信號量對象。 CreateParam.InitialCount=InitialCount; CreateParam.MaximumCount=MaximumCount; Status=ObCreateObject(PspSemaphoreType, Name, sizeof(SEMAPHORE), (ULONG_PTR)&CreateParam, &SemaphoreObject); if(!EOS_SUCCESS(Status)){ returnStatus; } Status=ObCreateHandle(SemaphoreObject,SemaphoreHandle); if(!EOS_SUCCESS(Status)){ ObDerefObject(SemaphoreObject); } returnStatus;}//semaphore對象的signal操作函數(shù)。STATUSPsReleaseSemaphoreObject( INHANDLEHandle, INLONGReleaseCount, INPLONGPreviousCount){ STATUSStatus; PSEMAPHORESemaphore; if(ReleaseCount<1){ returnSTATUS_INVALID_PARAMETER; }//由semaphore句柄得到semaphore對象的指針。 Status=ObRefObjectByHandle(Handle,PspSemaphoreType,(PVOID*)&Semaphore); if(EOS_SUCCESS(Status)){ Status=PsReleaseSemaphore(Semaphore,ReleaseCount,PreviousCount); ObDerefObject(Semaphore); } returnStatus;}4.程序運(yùn)行時(shí)的初值和運(yùn)行結(jié)果4.1準(zhǔn)備實(shí)驗(yàn)按照下面的步驟準(zhǔn)備本次實(shí)驗(yàn):1.啟動(dòng)OSLab。2.新建一個(gè)EOSKernel項(xiàng)目。3.生成EOSKernel項(xiàng)目,從而在該項(xiàng)目文件夾中生成SDK文件夾。4.新建一個(gè)EOS應(yīng)用程序項(xiàng)目。5.使用在第3步生成的SDK文件夾覆蓋EOS應(yīng)用程序項(xiàng)目文件夾中的SDK文件夾。4.2使用EOS的信號量解決生產(chǎn)者-消費(fèi)者問題在本實(shí)驗(yàn)文件夾中,提供了使用EOS的信號量解決生產(chǎn)者-消費(fèi)者問題的參考源代碼文件pc.c。使用OSLab打開此文件(將文件拖動(dòng)到OSLab窗口中釋放即可打開)按照下面的步驟查看生產(chǎn)者-消費(fèi)者同步執(zhí)行的過程:使用pc.c文件中的源代碼,替換之前創(chuàng)建的EOS應(yīng)用程序項(xiàng)目中EOSApp.c文件內(nèi)的源代碼。2.按F7生成修改后的EOS應(yīng)用程序項(xiàng)目。3.按F5啟動(dòng)調(diào)試。OSLab會首先彈出一個(gè)調(diào)試異常對話框。4.在調(diào)試異常對話框中選擇“否”,繼續(xù)執(zhí)行。5.立即激活虛擬機(jī)窗口查看生產(chǎn)者-消費(fèi)者同步執(zhí)行的過程。6.待應(yīng)用程序執(zhí)行完畢后,結(jié)束此次調(diào)試。4.3調(diào)試EOS信號量的工作過程4.3.1創(chuàng)建信號量信號量結(jié)構(gòu)體(SEMAPHORE)中的各個(gè)成員變量是由API函數(shù)CreateSemaphore的對應(yīng)參數(shù)初始化的,查看main函數(shù)中創(chuàng)建Empty和Full信號量使用的參數(shù)有哪些不同,又有哪些相同,思考其中的原因。按照下面的步驟調(diào)試信號量創(chuàng)建的過程:1.按F5啟動(dòng)調(diào)試EOS應(yīng)用項(xiàng)目。OSLab會首先彈出一個(gè)調(diào)試異常對話框。2.在調(diào)試異常對話框中選擇“是”,調(diào)試會中斷。3.在main函數(shù)中創(chuàng)建Empty信號量的代碼行(第77行)EmptySemaphoreHandle=CreateSemaphore(BUFFER_SIZE,BUFFER_SIZE,NULL);添加一個(gè)斷點(diǎn)。4.按F5繼續(xù)調(diào)試,到此斷點(diǎn)處中斷。5.按F11調(diào)試進(jìn)入CreateSemaphore函數(shù)??梢钥吹酱薃PI函數(shù)只是調(diào)用了EOS內(nèi)核中的PsCreateSemaphoreObject函數(shù)來創(chuàng)建信號量對象。6.按F11調(diào)試進(jìn)入semaphore.c文件中的PsCreateSemaphoreObject函數(shù)。在此函數(shù)中,會在EOS內(nèi)核管理的內(nèi)存中創(chuàng)建一個(gè)信號量對象(分配一塊內(nèi)存),而初始化信號量對象中各個(gè)成員的操作是在PsInitializeSemaphore函數(shù)中完成的。7.在semaphore.c文件的頂部查找到PsInitializeSemaphore函數(shù)的定義(第19行),在此函數(shù)的第一行(第39行)代碼處添加一個(gè)斷點(diǎn)。8.按F5繼續(xù)調(diào)試,到斷點(diǎn)處中斷。觀察PsInitializeSemaphore函數(shù)中用來初始化信號量結(jié)構(gòu)體成員的值,應(yīng)該和傳入CreateSemaphore函數(shù)的參數(shù)值是一致的。9.按F10單步調(diào)試PsInitializeSemaphore函數(shù)執(zhí)行的過程,查看信號量結(jié)構(gòu)體被初始化的過程。打開“調(diào)用堆?!贝翱?,查看函數(shù)的調(diào)用層次。4.3.2等待、釋放信號量4.3.2.1等待信號量(不阻塞)生產(chǎn)者和消費(fèi)者剛開始執(zhí)行時(shí),用來放產(chǎn)品的緩沖區(qū)都是空的,所以生產(chǎn)者在第一次調(diào)用WaitForSingleObject函數(shù)等待Empty信號量時(shí),應(yīng)該不需要阻塞就可以立即返回。按照下面的步驟調(diào)試:1.刪除所有的斷點(diǎn)(防止有些斷點(diǎn)影響后面的調(diào)試)。2.在eosapp.c文件的Producer函數(shù)中,等待Empty信號量的代碼行(第144行)WaitForSingleObject(EmptySemaphoreHandle,INFINITE);添加一個(gè)斷點(diǎn)。3.按F5繼續(xù)調(diào)試,到斷點(diǎn)處中斷。4.WaitForSingleObject函數(shù)最終會調(diào)用內(nèi)核中的PsWaitForSemaphore函數(shù)完成等待操作。所以,在semaphore.c文件中PsWaitForSemaphore函數(shù)的第一行(第68行)添加一個(gè)斷點(diǎn)。5.按F5繼續(xù)調(diào)試,到斷點(diǎn)處中斷。6.按F10單步調(diào)試,直到完成PsWaitForSemaphore函數(shù)中的所有操作。可以看到此次執(zhí)行并沒有進(jìn)行等待,只是將Empty信號量的計(jì)數(shù)減少了1(由10變?yōu)榱?)就返回了。4.3.2.2釋放信號量(不喚醒)1.刪除所有的斷點(diǎn)(防止有些斷點(diǎn)影響后面的調(diào)試)。2.在eosapp.c文件的Producer函數(shù)中,釋放Full信號量的代碼行(第152行)ReleaseSemaphore(FullSemaphoreHandle,1,NULL);添加一個(gè)斷點(diǎn)。3.按F5繼續(xù)調(diào)試,到斷點(diǎn)處中斷。4.按F11調(diào)試進(jìn)入ReleaseSemaphore函數(shù)。5.繼續(xù)按F11調(diào)試進(jìn)入PsReleaseSemaphoreObject函數(shù)。6.先使用F10單步調(diào)試,當(dāng)黃色箭頭指向第269行時(shí)使用F11單步調(diào)試,進(jìn)入PsReleaseSemaphore函數(shù)。7.按F10單步調(diào)試,直到完成PsReleaseSemaphore函數(shù)中的所有操作。可以看到此次執(zhí)行沒有喚醒其它線程(因?yàn)榇藭r(shí)沒有線程在Full信號量上被阻塞),只是將Full信號量的計(jì)數(shù)增加了1(由0變?yōu)榱?)。生產(chǎn)者線程通過等待Empty信號量使空緩沖區(qū)數(shù)量減少了1,通過釋放Full信號量使?jié)M緩沖區(qū)數(shù)量增加了1,這樣就表示生產(chǎn)者線程生產(chǎn)了一個(gè)產(chǎn)品并占用了一個(gè)緩沖區(qū)。4.3.2.3等待信號量(阻塞)由于開始時(shí)生產(chǎn)者線程生產(chǎn)產(chǎn)品的速度較快,而消費(fèi)者線程消費(fèi)產(chǎn)品的速度較慢,所以當(dāng)緩沖池中所有的緩沖區(qū)都被產(chǎn)品占用時(shí),生產(chǎn)者在生產(chǎn)新的產(chǎn)品時(shí)就會被阻塞,下面調(diào)試這種情況。1.結(jié)束之前的調(diào)試。2.刪除所有的斷點(diǎn)。3.按F5重新啟動(dòng)調(diào)試。OSLab會首先彈出一個(gè)調(diào)試異常對話框。4.在調(diào)試異常對話框中選擇“是”,調(diào)試會中斷。5.在semaphore.c文件中的PsWaitForSemaphore函數(shù)的PspWait(&Semaphore->WaitListHead,INFINITE);代碼行(第78行)添加一個(gè)斷點(diǎn)。6.按F5繼續(xù)調(diào)試,并立即激活虛擬機(jī)窗口查看輸出。開始時(shí)生產(chǎn)者、消費(fèi)者都不會被信號量阻塞,同步執(zhí)行一段時(shí)間后才在斷點(diǎn)處中斷。7.中斷后,查看“調(diào)用堆?!贝翱?,有Producer函數(shù)對應(yīng)的堆棧幀,說明此次調(diào)用是從生產(chǎn)者線程函數(shù)進(jìn)入的。8.在“調(diào)用堆?!贝翱谥须p擊Producer函數(shù)所在的堆棧幀,綠色箭頭指向等待Empty信號量的代碼行,查看Producer函數(shù)中變量i的值為14,表示生產(chǎn)者線程正在嘗試生產(chǎn)14號產(chǎn)品。9.在調(diào)用堆棧窗口中雙擊PsWaitForSemaphore函數(shù)的堆棧幀,查看Empty信號量計(jì)數(shù)(Semaphore->Count)的值為-1,所以會調(diào)用PspWait函數(shù)將生產(chǎn)者線程放入Empty信號量的等待隊(duì)列中進(jìn)行等待(讓出CPU)。10.激活虛擬機(jī)窗口查看輸出的結(jié)果。生產(chǎn)了從0到13的14個(gè)產(chǎn)品,但是只消費(fèi)了從0到3的4個(gè)產(chǎn)品,所以緩沖池中的10個(gè)緩沖區(qū)就都被占用了,這與之前調(diào)試的結(jié)果是一致的。4.3.2.4釋放信號量(喚醒)只有當(dāng)消費(fèi)者線程從緩沖池中消費(fèi)了一個(gè)產(chǎn)品,從而產(chǎn)生一個(gè)空緩沖區(qū)后,生產(chǎn)者線程才會被喚醒并繼續(xù)生產(chǎn)14號產(chǎn)品。可以按照下面的步驟調(diào)試:1.刪除所有斷點(diǎn)。2.在eosapp.c文件的Consumer函數(shù)中,釋放Empty信號量的代碼行(第180行)ReleaseSemaphore(EmptySemaphoreHandle,1,NULL);添加一個(gè)斷點(diǎn)。3.按F5繼續(xù)調(diào)試,到斷點(diǎn)處中斷。4.查看Consumer函數(shù)中變量i的值為4,說明已經(jīng)消費(fèi)了4號產(chǎn)品。5.按照中的方法使用F10和F11調(diào)試進(jìn)入PsReleaseSemaphore函數(shù)。6.查看PsReleaseSemaphore函數(shù)中Empty信號量計(jì)數(shù)(Semaphore->Count)的值為-1,和生產(chǎn)者線程被阻塞時(shí)的值是一致的。7.按F10單步調(diào)試PsReleaseSemaphore函數(shù),直到在代碼行(第132行)PspWakeThread(&Semaphore->WaitListHead,STATUS_SUCCESS);處中斷。此時(shí)Empty信號量計(jì)數(shù)的值已經(jīng)由-1增加為了0,需要調(diào)用PspWakeThread函數(shù)喚醒阻塞在Empty信號量等待隊(duì)列中的生產(chǎn)者線程(放入就緒隊(duì)列中),然后調(diào)用PspSchedule函數(shù)執(zhí)行調(diào)度,這樣生產(chǎn)者線程就得以繼續(xù)執(zhí)行。按照下面的步驟驗(yàn)證生產(chǎn)者線程被喚醒后,是從之前被阻塞時(shí)的狀態(tài)繼續(xù)執(zhí)行的:在semaphore.c文件中PsWaitForSemaphore函數(shù)的最后一行(第83行)代碼處添加一個(gè)斷點(diǎn)。2.按F5繼續(xù)調(diào)試,在斷點(diǎn)處中斷。3.查看PsWaitForSemaphore函數(shù)中Empty信號量計(jì)數(shù)(Semaphore->Count)的值為0,和生產(chǎn)者線程被喚醒時(shí)的值是一致的。4.在“調(diào)用堆?!贝翱谥锌梢钥吹绞怯蒔roducer函數(shù)進(jìn)入的。激活Producer函數(shù)的堆棧幀,查看Producer函數(shù)中變量i的值為14,表明之前被阻塞的、正在嘗試生產(chǎn)14號產(chǎn)品的生產(chǎn)者線程已經(jīng)從PspWait函數(shù)返回并繼續(xù)執(zhí)行了。5.結(jié)束此次調(diào)試。4.4修改EOS的信號量算法4.4.1要求在目前EOSKernel項(xiàng)目的ps/semaphore.c文件中,PsWaitForSemaphore函數(shù)的Milliseconds參數(shù)只能是INFINITE,PsReleaseSemaphore函數(shù)的ReleaseCount參數(shù)只能是1?,F(xiàn)在要求同時(shí)修改PsWaitForSemaphore函數(shù)和PsReleaseSemaphore函數(shù)中的代碼,使這兩個(gè)參數(shù)能夠真正起到作用,使信號量對象支持等待超時(shí)喚醒功能和批量釋放功能。4.4.2提示修改PsWaitForSemaphore函數(shù)時(shí)要注意:對于支持等待超時(shí)喚醒功能的信號量,其計(jì)數(shù)值只能是大于等于0。當(dāng)計(jì)數(shù)值大于0時(shí),表示信號量為signaled狀態(tài);當(dāng)計(jì)數(shù)值等于0時(shí),表示信號量為nonsignaled狀態(tài)。所以,PsWaitForSemaphore函數(shù)中原有的代碼段Semaphore->Count--;if(Semaphore->Count<0){PspWait(&Semaphore->WaitListHead,INFINITE);}應(yīng)被修改為:先用計(jì)數(shù)值和0比較,當(dāng)計(jì)數(shù)值大于0時(shí),將計(jì)數(shù)值減1后直接返回成功;當(dāng)計(jì)數(shù)值等于0時(shí),調(diào)用PspWait函數(shù)阻塞線程的執(zhí)行(將參數(shù)Milliseconds做為PspWait函數(shù)的第二個(gè)參數(shù),并使用PspWait函數(shù)的返回值做為返回值)。在函數(shù)開始定義一個(gè)STATUS類型的變量,用來保存不同情況下的返回值,并在函數(shù)最后返回此變量的值。絕不能在原子操作的中途返回!在EOSKernel項(xiàng)目ps/sched.c文件的第190行查看PspWait函數(shù)的說明和源代碼。修改PsReleaseSemaphore函數(shù)時(shí)要注意:編寫一個(gè)使用ReleaseCount做為計(jì)數(shù)器的循環(huán)體,來替換PsReleaseSemaphore函數(shù)中原有的代碼段Semaphore->Count++;if(Semaphore->Count<=0){PspWakeThread(&Semaphore->WaitListHead,STATUS_SUCCESS);}在循環(huán)體中完成下面的工作:1.如果被阻塞的線程數(shù)量大于等于ReleaseCount,則循環(huán)結(jié)束后,有ReleaseCount個(gè)線程會被喚醒,而且信號量計(jì)數(shù)的值仍然為0;2.如果被阻塞的線程數(shù)量(可以為0)小于ReleaseCount,則循環(huán)結(jié)束后,所有被阻塞的線程都會被喚醒,并且信號量的計(jì)數(shù)值=ReleaseCount-之前被阻塞線程的數(shù)量+之前信號量的計(jì)數(shù)值。
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 公司借款合同書集錦
- 勞動(dòng)合同法第四條
- 國際貿(mào)易貨物買賣合同
- 交通安全統(tǒng)籌服務(wù)合同
- 醫(yī)院聘用醫(yī)師協(xié)議書
- 2025年漯河貨運(yùn)資格證考試答案
- 借貸擔(dān)保合同協(xié)議5篇
- 農(nóng)場整體出租合同范本
- 買賣礦居間合同范本
- 農(nóng)村豬種出售合同范本
- 供應(yīng)商開發(fā)流程及質(zhì)量要求
- 2024年技術(shù)監(jiān)督質(zhì)檢職業(yè)技能考試-電力技術(shù)監(jiān)督上崗員(中國華能)筆試歷年真題薈萃含答案
- 反假幣測試附有答案
- 怎樣調(diào)動(dòng)員工積極性
- 2024年內(nèi)科護(hù)理學(xué)(第七版)期末考試復(fù)習(xí)題庫(含答案)
- 【上市公司的財(cái)務(wù)風(fēng)險(xiǎn)的分析和防范:以三只松鼠為例10000字(論文)】
- 急診科培訓(xùn)急診科與其他科室的協(xié)作與溝通
- JCT414-2017 硅藻土的標(biāo)準(zhǔn)
- 肌肉注射評分標(biāo)準(zhǔn)
- 鋼結(jié)構(gòu)主要技術(shù)標(biāo)準(zhǔn)和要求
- 臘八粥 第一課時(shí)自學(xué)導(dǎo)學(xué)單
評論
0/150
提交評論