進程的同步.doc_第1頁
進程的同步.doc_第2頁
進程的同步.doc_第3頁
進程的同步.doc_第4頁
進程的同步.doc_第5頁
已閱讀5頁,還剩8頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

操作系統(tǒng)實 驗 報 告課程名稱操作系統(tǒng)實驗實驗項目名稱進程的同步學號2009142212班級20100614姓名劉欣卓專業(yè)計算機科學與技術學生所在學院計算機科學與技術學院指導教師初妍實驗室名稱地點21#428 哈爾濱工程大學計算機科學與技術學院一、實驗概述1. 實驗名稱第三講 進程的同步2. 實驗目的使用EOS的信號量,編程解決生產(chǎn)者消費者問題,理解進程同步的意義。調(diào)試跟蹤EOS信號量的工作過程,理解進程同步的原理。 修改EOS的信號量算法,使之支持等待超時喚醒功能(有限等待),加深理解進程同步的原理。 3. 實驗類型驗證性實驗、設計性試驗4. 實驗內(nèi)容(1)準備實驗啟動OS Lab。新建一個EOS Kernel項目。 生成EOS Kernel項目,從而在該項目文件夾中生成SDK文件夾。 新建一個EOS應用程序項目。 使用在第3步生成的SDK文件夾覆蓋EOS應用程序項目文件夾中的SDK文件夾。 (2)生產(chǎn)者消費者同步執(zhí)行的過程使用pc.c文件中的源代碼,替換之前創(chuàng)建的EOS應用程序項目中EOSApp.c文件內(nèi)的源代碼。按F7生成修改后的EOS應用程序項目。按F5啟動調(diào)試。OS Lab會首先彈出一個調(diào)試異常對話框。 在調(diào)試異常對話框中選擇“否”,繼續(xù)執(zhí)行。立即激活虛擬機窗口查看生產(chǎn)者消費者同步執(zhí)行的過程。待應用程序執(zhí)行完畢后,結束此次調(diào)試。 (3) 調(diào)試EOS信號量的工作過程I 創(chuàng)建信號量按F5啟動調(diào)試EOS應用項目。OS Lab會首先彈出一個調(diào)試異常對話框。 在調(diào)試異常對話框中選擇“是”,調(diào)試會中斷。在main函數(shù)中創(chuàng)建Empty信號量的代碼行(第77行)EmptySemaphoreHandle = CreateSemaphore(BUFFER_SIZE, BUFFER_SIZE, NULL); 添加一個斷點。按F5繼續(xù)調(diào)試,到此斷點處中斷。 按F11調(diào)試進入CreateSemaphore函數(shù)。可以看到此API函數(shù)只是調(diào)用了EOS內(nèi)核中的PsCreateSemaphoreObject函數(shù)來創(chuàng)建信號量對象。按F11調(diào)試進入semaphore.c文件中的PsCreateSemaphoreObject函數(shù)。在此函數(shù)中,會在EOS內(nèi)核管理的內(nèi)存中創(chuàng)建一個信號量對象(分配一塊內(nèi)存),而初始化信號量對象中各個成員的操作是在PsInitializeSemaphore函數(shù)中完成的。在semaphore.c文件的頂部查找到PsInitializeSemaphore函數(shù)的定義(第19行),在此函數(shù)的第一行(第39行)代碼處添加一個斷點。按F5繼續(xù)調(diào)試,到斷點處中斷。觀察PsInitializeSemaphore函數(shù)中用來初始化信號量結構體成員的值,應該和傳入CreateSemaphore函數(shù)的參數(shù)值是一致的。按F10單步調(diào)試PsInitializeSemaphore函數(shù)執(zhí)行的過程,查看信號量結構體被初始化的過程。打開“調(diào)用堆?!贝翱?,查看函數(shù)的調(diào)用層次。 II 等待、釋放信號量1、等待信號量(不阻塞)刪除所有的斷點。在eosapp.c文件的Producer函數(shù)中,等待Empty信號量的代碼行(第144行) WaitForSingleObject(EmptySemaphoreHandle, INFINITE); 添加一個斷點。 按F5繼續(xù)調(diào)試,到斷點處中斷。WaitForSingleObject 函數(shù)最終會調(diào)用內(nèi)核中的PsWaitForSemaphore函數(shù)完成等待操作。所以,在semaphore.c文件中PsWaitForSemaphore函數(shù)的第一行(第68行)添加一個斷點。按F5繼續(xù)調(diào)試,到斷點處中斷。 按F10單步調(diào)試,直到完成PsWaitForSemaphore函數(shù)中的所有操作。 2、釋放信號量(不喚醒)刪除所有的斷點。在eosapp.c文件的Producer函數(shù)中,釋放Full信號量的代碼行(第152行) ReleaseSemaphore(FullSemaphoreHandle, 1, NULL); 添加一個斷點。 按F5繼續(xù)調(diào)試,到斷點處中斷。 按F11調(diào)試進入ReleaseSemaphore函數(shù)。繼續(xù)按F11調(diào)試進入PsReleaseSemaphoreObject函數(shù)。先使用F10單步調(diào)試,當黃色箭頭指向第269行時使用F11單步調(diào)試,進入PsReleaseSemaphore函數(shù)。 按F10單步調(diào)試,直到完成PsReleaseSemaphore函數(shù)中的所有操作。3、等待信號量(阻塞)結束之前的調(diào)試。刪除所有的斷點。按F5重新啟動調(diào)試。OS Lab會首先彈出一個調(diào)試異常對話框。在調(diào)試異常對話框中選擇“是”,調(diào)試會中斷。 在semaphore.c文件中的PsWaitForSemaphore函數(shù)的 PspWait(&Semaphore-WaitListHead, INFINITE); 代碼行(第78行)添加一個斷點。按F5繼續(xù)調(diào)試,并立即激活虛擬機窗口查看輸出。開始時生產(chǎn)者、消費者都不會被信號量阻塞,同步執(zhí)行一段時間后才在斷點處中斷。中斷后,查看“調(diào)用堆棧”窗口,有Producer函數(shù)對應的堆棧幀,說明此次調(diào)用是從生產(chǎn)者線程函數(shù)進入的。 在“調(diào)用堆?!贝翱谥须p擊Producer函數(shù)所在的堆棧幀,綠色箭頭指向等待Empty信號量的代碼行,查看Producer函數(shù)中變量i的值為14,表示生產(chǎn)者線程正在嘗試生產(chǎn)14號產(chǎn)品。 在“調(diào)用堆棧”窗口中雙擊PsWaitForSemaphore函數(shù)的堆棧幀,查看Empty信號量計數(shù)(Semaphore-Count)的值為-1,所以會調(diào)用PspWait函數(shù)將生產(chǎn)者線程放入Empty信號量的等待隊列中進行等待(讓出CPU)。激活虛擬機窗口查看輸出的結果。生產(chǎn)了從0到13的14個產(chǎn)品,但是只消費了從0到3的4個產(chǎn)品,所以緩沖池中的10個緩沖區(qū)就都被占用了,這與之前調(diào)試的結果是一致的。 4、釋放信號量(喚醒)刪除所有斷點。在eosapp.c文件的Consumer函數(shù)中,釋放Empty信號量的代碼行(第180行) ReleaseSemaphore(EmptySemaphoreHandle, 1, NULL); 添加一個斷點。按F5繼續(xù)調(diào)試,到斷點處中斷。查看Consumer函數(shù)中變量i的值為4,說明已經(jīng)消費了4號產(chǎn)品。按照釋放信號量(不喚醒)中的方法使用F10和F11調(diào)試進入PsReleaseSemaphore函數(shù)。查看PsReleaseSemaphore函數(shù)中Empty信號量計數(shù)(Semaphore-Count)的值為-1,和生產(chǎn)者線程被阻塞時的值是一致的。按F10單步調(diào)試PsReleaseSemaphore函數(shù),直到在代碼行(第132行) PspWakeThread(&Semaphore-WaitListHead, STATUS_SUCCESS); 處中斷。此時Empty信號量計數(shù)的值已經(jīng)由-1增加為了0,需要調(diào)用PspWakeThread函數(shù)喚醒阻塞在Empty信號量等待隊列中的生產(chǎn)者線程(放入就緒隊列中),然后調(diào)用PspSchedule函數(shù)執(zhí)行調(diào)度,這樣生產(chǎn)者線程就得以繼續(xù)執(zhí)行。 III 驗證生產(chǎn)者線程被喚醒后從被阻塞時的狀態(tài)繼續(xù)執(zhí)行在semaphore.c文件中PsWaitForSemaphore函數(shù)的最后一行(第83行)代碼處添加一個斷點。按F5繼續(xù)調(diào)試,在斷點處中斷。查看PsWaitForSemaphore函數(shù)中Empty信號量計數(shù)(Semaphore-Count)的值為0,和生產(chǎn)者線程被喚醒時的值是一致的。在“調(diào)用堆?!贝翱谥锌梢钥吹绞怯蒔roducer函數(shù)進入的。激活Producer函數(shù)的堆棧幀,查看Producer函數(shù)中變量i的值為14,表明之前被阻塞的、正在嘗試生產(chǎn)14號產(chǎn)品的生產(chǎn)者線程已經(jīng)從PspWait函數(shù)返回并繼續(xù)執(zhí)行了。結束此次調(diào)試。 (4)修改EOS的信號量算法修改PsWaitForSemaphore函數(shù)先用計數(shù)值和0比較,當計數(shù)值大于0時,將計數(shù)值減1后直接返回成功;當計數(shù)值等于0時,調(diào)用PspWait函數(shù)阻塞線程的執(zhí)行(將參數(shù)Milliseconds做為PspWait函數(shù)的第二個參數(shù),并使用PspWait函數(shù)的返回值做為返回值)。在函數(shù)開始定義一個STATUS類型的變量,用來保存不同情況下的返回值,并在函數(shù)最后返回此變量的值。絕不能在原子操作的中途返回! 修改PsReleaseSemaphore函數(shù)如果被阻塞的線程數(shù)量大于等于ReleaseCount,則循環(huán)結束后,有ReleaseCount個線程會被喚醒,而且信號量計數(shù)的值仍然為0; 如果被阻塞的線程數(shù)量(可以為0)小于ReleaseCount,則循環(huán)結束后,所有被阻塞的線程都會被喚醒,并且信號量的計數(shù)值ReleaseCount之前被阻塞線程的數(shù)量之前信號量的計數(shù)值。 (5)測試方法使用修改完畢的EOS Kernel項目生成完全版本的SDK文件夾,并覆蓋之前的生產(chǎn)者消費者應用程序項目的SDK文件夾。按F5調(diào)試執(zhí)行原有的生產(chǎn)者消費者應用程序項目,結果必須仍然與圖13-2一致。如果有錯誤,可以調(diào)試內(nèi)核代碼來查找錯誤,然后在內(nèi)核項目中修改, 將Producer函數(shù)中等待Empty信號量的代碼行WaitForSingleObject(EmptySemaphoreHandle, INFINITE); 替換為while(WAIT_TIMEOUT = WaitForSingleObject(EmptySemaphoreHandle,300)printf(Producer wait for empty semaphore timeoutn); 將Consumer函數(shù)中等待Full信號量的代碼行WaitForSingleObject(FullSemaphoreHandle, INFINITE);替換為while(WAIT_TIMEOUT=WaitForSingleObject(FullSemaphoreHandle,300) printf(Consumer wait for full semaphore timeoutn); 啟動調(diào)試新的生產(chǎn)者消費者項目,查看在虛擬機中輸出的結果,驗證信號量超時等待功能是否能夠正常執(zhí)行。如果有錯誤,可以調(diào)試內(nèi)核代碼來查找錯誤,然后在內(nèi)核項目中修改。如果超時等待功能已經(jīng)能夠正常執(zhí)行,可以考慮將消費者線程修改為一次消費兩個產(chǎn)品,來測試ReleaseCount參數(shù)是否能夠正常使用。使用實驗文件夾中NewConsumer.c文件中的Consumer函數(shù)替換原有的Consumer函數(shù)。 二、實驗環(huán)境Tevation OS Lab 1.0.3.99003、 實驗過程一、設計思路:1 啟動OS Lab 3.1 準備實驗 3.2 使用EOS的信號量解決生產(chǎn)者消費者問題 3.3 調(diào)試EOS信號量的工作過程 3.3.1 創(chuàng)建信號量 3.3.2 等待、釋放信號量 3.3.2.1 等待信號量(不阻塞) 3.3.2.2 釋放信號量(不喚醒) 3.3.2.3 等待信號量(阻塞) 3.3.2.4 釋放信號量(喚醒) 3.4 修改EOS的信號量算法 3.4.1 要求 3.4.2 提示 3.4.3 測試方法 3.5 退出系統(tǒng)并保存oud文件2、 算法設計:本次實驗要求修改信號量算法1、 修改PsWaitForSemaphore函數(shù)PsWaitForSemaphore函數(shù)中原有的代碼段Semaphore-Count-; if (Semaphore-Count WaitListHead, INFINITE); 應被修改為:先用計數(shù)值和0比較,當計數(shù)值大于0時,將計數(shù)值減1后直接返回成功;當計數(shù)值等于0時,調(diào)用PspWait函數(shù)阻塞線程的執(zhí)行(將參數(shù)Milliseconds做為PspWait函數(shù)的第二個參數(shù),并使用PspWait函數(shù)的返回值做為返回值)。 在函數(shù)開始定義一個STATUS類型的變量,用來保存不同情況下的返回值,并在函數(shù)最返回此變量的值。絕不能在原子操作的中途返回! 在EOS Kernel項目ps/sched.c文件的第190行查看PspWait函數(shù)的說明和源代碼。 按要求應修改為:if (Semaphore-Count 0)Semaphore-Count-;flag=STATUS_SUCCESS;/信號量大于0,說明可以為線程分配資源else flag=PspWait(&Semaphore-WaitListHead, Milliseconds);/信號量小于0,需要等待KeEnableInterrupts(IntState); / 原子操作完成,恢復中斷。return flag;2、 修改PsReleaseSemaphore函數(shù)編寫一個使用ReleaseCount做為計數(shù)器的循環(huán)體,來替換PsReleaseSemaphore函數(shù)中原有的代碼段Semaphore-Count+;if (Semaphore-Count WaitListHead, STATUS_SUCCESS); 在循環(huán)體中完成下面的工作:1. 如果被阻塞的線程數(shù)量大于等于ReleaseCount,則循環(huán)結束后,有ReleaseCount個線程會被喚醒,而且信號量計數(shù)的值仍然為0; 2. 如果被阻塞的線程數(shù)量(可以為0)小于ReleaseCount,則循環(huán)結束后,所有被阻塞的線程都會被喚醒,并且信號量的計數(shù)值ReleaseCount之前被阻塞線程的數(shù)量之前信號量的計數(shù)值。 在EOS Kernel項目ps/sched.c文件的第294行查看PspWakeThread函數(shù)的說明和源代碼。在循環(huán)的過程中可以使用宏定義函數(shù)ListIsEmpty判斷信號量的等待隊列是否為空,例如 ListIsEmpty(&Semaphore-WaitListHead) 可以在EOS Kernel項目inc/rtl.h文件的第113行查看此宏定義的源代碼。 按要求應修改為:while (!ListIsEmpty(&Semaphore-WaitListHead)&(ReleaseCount)PspWakeThread(&Semaphore-WaitListHead, STATUS_SUCCESS);PspThreadSchedule();ReleaseCount-;Semaphore-Count = Semaphore-Count + ReleaseCount;/ 可能有線程被喚醒,執(zhí)行線程調(diào)度。Status = STATUS_SUCCESS;KeEnableInterrupts(IntState); / 原子操作完成,恢復中斷。return Status;3、 測試方法修改完畢后,可以按照下面的方法進行測試: 1. 使用修改完畢的EOS Kernel項目生成完全版本的SDK文件夾,并覆蓋之前的生產(chǎn)者消費者應用程序項目的SDK文件夾。 2. 按F5調(diào)試執(zhí)行原有的生產(chǎn)者消費者應用程序項目,結果必須仍然與圖13-2一致。如果有錯誤,可以調(diào)試內(nèi)核代碼來查找錯誤,然后在內(nèi)核項目中修改,并重復步驟1。 3. 將Producer函數(shù)中等待Empty信號量的代碼行 WaitForSingleObject(EmptySemaphoreHandle, INFINITE);替換為 while(WAIT_TIMEOUT = WaitForSingleObject(EmptySemaphoreHandle, 300) printf(Producer wait for empty semaphore timeoutn); 將Consumer函數(shù)中等待Full信號量的代碼行 WaitForSingleObject(FullSemaphoreHandle, INFINITE);替換為while(WAIT_TIMEOUT = WaitForSingleObject(FullSemaphoreHandle, 300) printf(Consumer wait for full semaphore timeoutn); 啟動調(diào)試新的生產(chǎn)者消費者項目,查看在虛擬機中輸出的結果,驗證信號量超時等待功能是否能夠正常執(zhí)行。如果有錯誤,可以調(diào)試內(nèi)核代碼來查找錯誤,然后在內(nèi)核項目中修改,并重復步驟1。 如果超時等待功能已經(jīng)能夠正常執(zhí)行,可以考慮將消費者線程修改為一次消費兩個產(chǎn)品,來測試ReleaseCount參數(shù)是否能夠正常使用。使用實驗文件夾中NewConsumer.c文件中的Consumer函數(shù)替換原有的Consumer函數(shù)。 3、 實驗要求:1、 P143,生產(chǎn)者在生產(chǎn)了13號產(chǎn)品后本來要繼續(xù)生產(chǎn)14號產(chǎn)品,可此時生產(chǎn)者為什么必須等待消費者消費了4號產(chǎn)品后,才能生產(chǎn)14號產(chǎn)品呢?生產(chǎn)者和消費者是怎樣使用同步對象來實現(xiàn)該同步過程的呢?因為緩沖池已滿,此時生成了14個產(chǎn)品(013),只消費了4個(03),緩沖池大小為10,因此生產(chǎn)者必須等消費者消費了4號產(chǎn)品后,再生產(chǎn)14號產(chǎn)品。簡單地說,在同一地址空間執(zhí)行2個線程:生產(chǎn)者線程和消費者線程。生產(chǎn)者線程生產(chǎn)產(chǎn)品,放入緩沖池等待消費者消費,消費者線程從緩沖池中獲得產(chǎn)品,釋放緩沖池。當生產(chǎn)者線程生產(chǎn)物品時,如果緩沖池已滿,那么生產(chǎn)者線程必須等待消費者線程釋放出一個空緩沖區(qū)。當消費者線程消費物品時,如果沒有滿的緩沖區(qū),那么消費者線程將被阻塞,直到新的物品被生產(chǎn)出來。2、 P145-3.4 修改EOS的信號量算法(只看一次消費1個產(chǎn)品的,一次消費2個產(chǎn)品的可以寫到實驗報告中)修改方法請參考本實驗報告算法部分。下面給出運行截圖:修改前:修改后:3、 P147-四、 思考與練習-2. 繪制ps/semaphore.c文件內(nèi)PsWaitForSemaphore和PsReleaseSema

溫馨提示

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

評論

0/150

提交評論