




已閱讀5頁,還剩12頁未讀, 繼續(xù)免費閱讀
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
操作系統(tǒng)課設報告1. 概述31.1. 目的31.2. 主要完成的任務31.3. 使用的開發(fā)工具31.4. 解決的主要問題32. 使用的基本概念和原理32.1. 線程32.2. 線程的同步42.3. 模態(tài)對話框42.4. 原理43. 總體設計43.1. 確定基本的技術路線43.2. 軟件的總體結構43.3. 創(chuàng)建的進程和線程54. 詳細設計54.1. 利用的進程操作的函數(shù)、原語、API54.1.1. 信號量創(chuàng)建函數(shù)54.1.2. 互斥對象的創(chuàng)建.54.1.3. 線程創(chuàng)建函數(shù)64.1.4. 等待函數(shù)64.2. 模塊內部的流程和實現(xiàn)算法64.3. 全局變量的聲明85. 編碼設計95.1. 開發(fā)環(huán)境的設置和建立95.2. 編譯環(huán)境的設置95.3. 程序設計時要注意的事項105.4. 主要程序的代碼設計及注釋105.5. 解決的技術難點、經(jīng)常犯的錯誤146. 測試時出現(xiàn)的問題及其解決方法147. 軟件使用說明及運行結果147.1. 基本功能147.2. 需要運行的環(huán)境157.3. 安裝及運行157.4. 操作157.5. 運行結果158. 總結168.1. 操作系統(tǒng)課程設計完成情況168.2. 收獲和感受168.3. 經(jīng)驗總結169. 參考文獻171. 概述1.1. 目的 通過使用程序設計語言設計一個程序,模擬生產(chǎn)者消費者和搬運者對產(chǎn)品操作的過程。1.2. 主要完成的任務PutMove2Buff1Buff2Buff3GetMove1 圖1 Buffer操作 (1) 可以隨機產(chǎn)生字符數(shù)據(jù),由put操作放入Buff1,buffer中容量單位是字符。 (2) 提供良好圖形界面,顯示Buffer的操作過程。 (3) 可以設定各Buffer的容量、PUT、GET、Move操作的個數(shù); (4) 可以設定PUT、GET、Move操作的速度; (5) 實時顯示每個Buffer中數(shù)據(jù)的個數(shù)和數(shù)據(jù)的內容,空閑Buffer的空間的個數(shù); (6) 實時顯示線程、進程所處于等待(阻塞)狀態(tài)的個數(shù) (7) 程序運行結束,顯示匯總數(shù)據(jù): 總的運行時間; Buffer中數(shù)據(jù)的個數(shù); 已放入BUFFER的數(shù)據(jù)個數(shù); 已放已取的數(shù)據(jù)個數(shù); 平均每個buffer中的數(shù)據(jù)個數(shù)。1.3. 使用的開發(fā)工具使用MFC在VC+6.0上完成程序的設計。1.4. 解決的主要問題 (1)可以隨機產(chǎn)生字符數(shù)據(jù)。 (2)設計put,get,move的線程。 (3)可以設計buffer的容量,put,get,move的個數(shù)。 (4)控制put,get,move的速度。 (5)實時顯示buffer的內容。2. 使用的基本概念和原理2.1. 線程線程,有時被稱為輕量級進程(Lightweight Process,LWP),是程序執(zhí)行流的最小單元。線程是進程中的一個實體,是被系統(tǒng)獨立調度和分派的基本單位,線程自己不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。一個線程可以創(chuàng)建和撤消另一個線程,同一進程中的多個線程之間可以并發(fā)執(zhí)行。由于線程之間的相互制約,致使線程在運行中呈現(xiàn)出間斷性。線程也有就緒、阻塞和運行三種基本狀態(tài)。每一個程序都至少有一個線程,若程序只有一個線程,那就是程序本身。2.2. 線程的同步 臨界段:臨界段對象通過提供所有線程必須共享的對象來控制線程。只有擁有臨界段對象的線程才可以訪問保護資源(進行臨界區(qū)操作)。在另一個線程可以獲取對象的訪問權。用戶應用程序可能會使用臨界對象來阻止兩個線程同時訪問共享的資源發(fā)文件等。 互斥量:互斥量的工作方式和臨界段非常相似,其區(qū)別在于互斥量不公保護一個進程內的資源共享,而且還保護系統(tǒng)中進程之間的共享資源。它是通過為互斥量提供一個“互斥量名”來進行進程間資源共享協(xié)調的。 事件:事件對象用于給線程傳遞信號,指示線程中特定的操作可以開始或結束。除非線程已經(jīng)收到了這個事件信號,否則它將一直處于掛起狀態(tài)。當事件對象進入其信號狀態(tài)時,正在等待該事件的線程就可以開始執(zhí)行。例如,一個應用程序可以通過事件來通知線程它需要的數(shù)據(jù)已經(jīng)準備好。經(jīng)常利用事件進行線程之間的通信。 信號量:信號量與互斥相似,但是互斥只允許在同一時刻一個線程訪問它的數(shù)據(jù),而信號量允許多個線程在同一時刻訪問它的數(shù)據(jù)。WIN32 不知道哪一個線程擁有信號量,它只保證信號量使用的資源計數(shù)正確的設置。2.3. 模態(tài)對話框 模態(tài)對話框(Modal Dialogue Box,又叫做模式對話框),是指在用戶想要對對話框以外的應用程序進行操作時,必須首先對該對話框進行響應。如單擊【確定】或【取消】按鈕等將該對話框關閉。2.4. 原理 使用信號量作為同步互斥的工具,通過對BUFFER1、BUFFER2的容量,還有控制權設置不同的信號量來協(xié)調PUT、GET、MOVE線程,使其同步來實現(xiàn)P、V操作。3. 總體設計3.1. 確定基本的技術路線用MFC設計的,是面向對象的程序。3.2. 軟件的總體結構設置模塊,設置生產(chǎn)者消費者搬運者的初始值,及其它們的速度。顯示模塊,實時顯示生產(chǎn)者消費者搬運者及buffer的情況變化,還有匯總的情況。生產(chǎn)者消費者搬運者過程演示控制模塊,控制開始,停止及退出。 圖2 框架圖3.3. 創(chuàng)建的進程和線程 (1)DWORD WINAPI ThreadProduct(LPVOID lpParameter);/生產(chǎn)者線程 (2)DWORD WINAPI ThreadConsumer(LPVOID lpParameter);/生產(chǎn)者線程 (3)DWORD WINAPI ThreadMover1(LPVOID lpParameter);/搬運者1線程 (4)DWORD WINAPI ThreadMover2(LPVOID lpParameter);/搬運者2線程 (5)DWORD WINAPI ThreadBuffer1(LPVOID lpParameter);/顯示buffer1的線程 (6)DWORD WINAPI ThreadBuffer2(LPVOID lpParameter);/顯示buffer2的線程 (7)DWORD WINAPI ThreadBuffer3(LPVOID lpParameter);/顯示buffer3的線程 (8)DWORD WINAPI ThreadCount(LPVOID lpParameter);/匯總的線程 (9)DWORD WINAPI Threadtime(LPVOID lpParameter);/時間的線程4. 詳細設計4.1. 利用的進程操作的函數(shù)、原語、API 4.1.1. 信號量創(chuàng)建函數(shù) HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, / 安全屬性指針LONG lInitialCount, / 初始計數(shù)LONG lMaximumCount, / 最大計數(shù)LPCTSTR lpName / 對象名指針); 該函數(shù)創(chuàng)建一個信號量,llnitialCount 是對信號量的初始值,iMaximunCount為信號量的最大值,即信號量在一個范圍內有效,例empty=:CreateSemaphore(0,0,M,0);第二個0為empty信號量的初始值,M為信號量的最大值,在這個范圍內(0,M)信號量都是有信號的。4.1.2. 互斥對象的創(chuàng)建HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,安全屬性結構指針,可為NULL,表示默認安全性BOOL bInitialOwner,/是否占有該互斥量,TRUE:占有,F(xiàn)ALSE:不占有LPCTSTR lpName/設置互斥對象的名字);如果一個線程擁有了一個互斥對象后,當該線程運行完成后就要釋放該互斥對象,不然其他的線程得不到互斥對象則無法運行。用ReleaseMutex(HWND);操作它的具體作用是每調用它一次將互斥對象的計數(shù)器減一,直到減到零為止,此時釋放互斥對象,并將互斥對象中的線程id置零。它的使用條件是,互斥對象在哪個線程中被創(chuàng)建,就在哪個線程里面釋放。因為調用的時候會檢查當前線程的id是不是與互斥對象中保存的id一致,若一致,則此次操作有效,不一致,則無效。4.1.3. 線程創(chuàng)建函數(shù)HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes./線程安全屬性DWORD dwStackSize,/線程堆棧的初始化大小,等于0時為系統(tǒng)默認的堆棧大小PLTHREAD_START_ROUTINE lpStartAddress,/線程函數(shù)LPVOID lpParameter,/線程參數(shù)DWORD dwCreationFlags,/創(chuàng)建方式LPDWORD lpThreadId/線程標識符);該函數(shù)創(chuàng)建一個線程,如果沒有特殊需要除第三個參數(shù)外都可設為0,按系統(tǒng)的默認取值對待,主要是第三個參數(shù),它是線程程序的入口,線程序入口的標準形式為 UINT FUNCTION(LPVOID param)線程函數(shù)里可以傳一個指針做為參數(shù)(param),該參數(shù)由創(chuàng)建線程函數(shù)(CreateThread)里的第四個參數(shù)確定。4.1.4. 等待函數(shù) DWORD WaitForSingleObjec( HANDLE hHandle,/對象句柄 DWORD dwMilliseconds/等待的時間,單位為毫秒 )該函數(shù)在不同的應用里會有不同的意義,在信號量里應用時主要是判斷信號量是否有信號。第二個參數(shù)為等待時間,我們通常設為INFINITE,即為無限等待,在等待期間會將線程掛起,直到等待的信號量有信號。4.2. 模塊內部的流程和實現(xiàn)算法 設置6個信號量full1、empty1、hMutex1、full2、empty2、hMutex2,full3、empty3,hMutex3它們的含義和初值如下: (1)full1buffer1是否有數(shù)據(jù),初值為0; (2)empty1buffer1有空間,初值為M; (3)hMutex1buffer1是否可操作,初值為1; (4)full2buffer2是否有數(shù)據(jù),初值為0; (5)empty2buffer2有空間,初值為N; (6)hMutex2buffer2是否可操作,初值為1;(7)full3buffer3是否有數(shù)據(jù),初值為0;(8)empty3buffer3有空間,初值為Q;(9)hMutex3buffer3是否可操作,初值為1; 設置三類進程函數(shù),用信號量實現(xiàn)同步互斥,PUT,MOVE,GET算法如下: While()P(empty1); /*判斷buff1是否有空間,沒有則等待 */ P(hMutex1); /*是否可操作buffer1*/PUT; V(hMutex1); /*設置buff1可操作標志 */ V(full1); /*設置buff1有數(shù)據(jù)的標志 */ until false Move1 While()P(full1); /*判斷buffer1是否有數(shù)據(jù)*/P(empty2); /*判斷buffer2是否有空間*/ P(hMutex1); /*是否可操作buffer1 */P(hMutex2); /*是否可操作buffer2 */MOVE; V(hMutex1); /*設置buffer1可操作標志*/ V(hMutex2); /*設置buffer2可操作標志*/ V(empty1); /*設置buffer1有空間標志*/ V(full2); /*設置buffer2有數(shù)據(jù)標志*/ until false Move2 While()P(full2); /*判斷buffer2是否有數(shù)據(jù)*/P(empty3); /*判斷buffer3是否有空間*/ P(hMutex2); /*是否可操作buffer2 */P(hMutex3); /*是否可操作buffer3*/MOVE; V(hMutex2); /*設置buffer2可操作標志*/ V(hMutex3); /*設置buffer3可操作標志*/ V(empty2); /*設置buffer2有空間標志*/ V(full3); /*設置buffer3有數(shù)據(jù)標志*/ until false While()P(full3); /*判斷buffer3是否有數(shù)據(jù),沒有則等待 */ P(hMutex3); /*是否可操作buffer3*/GET; V(hMutex3); /*設置buffer3可操作標志 */ V(full3); /*設置buffer3有數(shù)據(jù)的標志 */ until false4.3. 全局變量的聲明 int put_buffer1=0;/放入buffer1的產(chǎn)品個數(shù); int move_buffer1=0;/從buffer1中取走的產(chǎn)品個數(shù); int move_buffer2=0;/從buffer2中取走的產(chǎn)品個數(shù); int get_buffer3=0;/從buffer3中取走的產(chǎn)品個數(shù); int m_time;/記錄時間 int buffer1;/buffer1中產(chǎn)品個數(shù) int buffer2;/buffer2中產(chǎn)品個數(shù) int buffer3;/buffer3中產(chǎn)品個數(shù) int consumer;/消費者個數(shù) int product;/生產(chǎn)者個數(shù) int mover;/搬運者一的個數(shù) int mover2;/搬運者二的個數(shù) int producterid=1;/生產(chǎn)者的id號 int moverid1;/搬運者1的id號 int moverid2;/搬運者2的id號 int consumer_id=1;/消費者的id int productid=101;/生產(chǎn)者生產(chǎn)出來的產(chǎn)品的id號 int name_product;/存儲隨機產(chǎn)品; int ioend=0;/判斷用的 int toend=1; int consumerid=101;/消費者消費的產(chǎn)品id號 int move1_consumerid=101;/搬運者搬運的產(chǎn)品的id號 int move2_consumerid=101; int put=1000;/put的速度 int move1=1000;/move1的速度 int move2=1000;/move2的速度 int get=1000;/get的速度 CString getget;/存獲取m_list_buffer里面的第0行的字符串; CString move;/存獲取m_list_buffer里面的第0行的字符串; CString putput;/存獲取m_list_buffer里面的第0行的字符串;5. 編碼設計5.1. 開發(fā)環(huán)境的設置和建立 (1)起動VISUAL C+ 6.0程序 (2)在菜單里選擇文件,子菜單里選擇新建,彈出新建對話框,如圖3所示。 圖3.新建工程 (3)在左邊的新建選項里選擇MFC AppWizardexe選項,右邊的project name里填入一個工程名,選擇OK按扭。選擇默認設置。5.2. 編譯環(huán)境的設置 在WINDOWS環(huán)境下的多線程中,為保證程序的正確性,必須使用用于多線程環(huán)境的正確的函數(shù)庫,在VC+ 6.0開發(fā)環(huán)境中在菜單工程中設置中進行選擇。步驟如下: (1)選擇PROJECT菜單中的SETTING.項; (2)在打開的表彰中選擇C/C+項; (3)選擇CATEGORY中的CODE GENERATION項; (4)在USE RUN-TIME LIBRARY中選擇MULTITHREADED; (5)單擊OK即可。 此時,在命令行方式下編譯選項由ML變?yōu)镸T,如圖4所示。 圖4.編譯環(huán)境5.3. 程序設計時要注意的事項(1)盡量避免全局變量的使用;(2)變量的命名要規(guī)范;(3)注意給代碼多寫注釋;(4)注意進行模塊化設計,寫相應的函數(shù)來完成相應的功能。5.4. 主要程序的代碼設計及注釋 (1)四個主要線程PUT,GET,MOVE1,MOVE2代碼實現(xiàn)。DWORD WINAPI ThreadProduct(LPVOID lpParameter)int j=producterid;/用j來標記第幾條線程;producterid+;while(toend)Sleep(put);CString str;CString str1;CString str2;WaitForSingleObject(SemaphoreEmpty,INFINITE);WaitForSingleObject(hMutex,INFINITE);put_buffer1+;/放進去一個產(chǎn)品,就加一;srand(unsigned)time(NULL);name_product=(rand()%26)+65;str.Format(%s%d%4d%s,工作者完成,j,put_buffer1,次生產(chǎn));str1.Format(%s%d%s%c,產(chǎn)品號:,productid+,產(chǎn)品名:,name_product);str2.Format(%s%d%s,線程,j,在運行,其他線程處于阻塞狀態(tài));m_list_product-DeleteString(0);m_list_product-DeleteString(0);m_list_product-InsertString(-1,str);m_list_product-InsertString(-1,str1);m_list_product-InsertString(-1,str2);m_list_buffer1-InsertString(-1,str1);Sleep(400);m_list_product-DeleteString(2);ReleaseMutex(hMutex);ReleaseSemaphore(SemaphoreFULL,1,NULL);return 1;DWORD WINAPI ThreadMover1(LPVOID lpParameter)int j=moverid1;moverid1+;while(toend)Sleep(move1);CString str;CString str1;CString str2;WaitForSingleObject(SemaphoreFULL,INFINITE);WaitForSingleObject(SemaphoreEmpty2,INFINITE);WaitForSingleObject(hMutex,INFINITE);WaitForSingleObject(hMutex2,INFINITE);move_buffer1+;/表示從buffer1移出的產(chǎn)品也是移入buffer2的產(chǎn)品個數(shù);str.Format(%s%d%s%4d%s,搬運者,j,buffer1-buffer2,move_buffer1,次搬運);str2.Format(%s%d%s,線程,j,在運行其他線程處于阻塞狀態(tài));m_list_buffer1-GetText(0,putput);m_list_move1-DeleteString(0);m_list_move1-DeleteString(0);m_list_move1-InsertString(-1,str);m_list_move1-InsertString(-1,putput);m_list_move1-InsertString(-1,str2);m_list_buffer1-DeleteString(0);m_list_buffer2-InsertString(-1,putput);Sleep(400);m_list_move1-DeleteString(2);ReleaseMutex(hMutex2); ReleaseMutex(hMutex); ReleaseSemaphore(SemaphoreFULL2,1,NULL);ReleaseSemaphore(SemaphoreEmpty,1,NULL);return 1;DWORD WINAPI ThreadMover2(LPVOID lpParameter)int j=moverid2;moverid2+;while(toend)Sleep(move2);CString str;CString str2;WaitForSingleObject(SemaphoreFULL2,INFINITE);WaitForSingleObject(SemaphoreEmpty3,INFINITE);WaitForSingleObject(hMutex2,INFINITE);WaitForSingleObject(hMutex3,INFINITE);move_buffer2+;/表示從buffer2移出的產(chǎn)品也是移入buffer3的產(chǎn)品個數(shù);str.Format(%s%d%s%4d%s,搬運者,j,buffer2-buffer3,move_buffer2,次搬運);str2.Format(%s%d%s,線程,j,在運行其他線程處于阻塞狀態(tài));m_list_buffer2-GetText(0,move);m_list_move2-DeleteString(0);m_list_move2-DeleteString(0);m_list_move2-InsertString(-1,str);m_list_move2-InsertString(-1,move);m_list_move2-InsertString(-1,str2);m_list_buffer2-DeleteString(0);m_list_buffer3-InsertString(-1,move);Sleep(400);m_list_move2-DeleteString(2);ReleaseMutex(hMutex3); ReleaseMutex(hMutex2); ReleaseSemaphore(SemaphoreFULL3,1,NULL);ReleaseSemaphore(SemaphoreEmpty2,1,NULL);return 1;DWORD WINAPI ThreadConsumer(LPVOID lpParameter)int j=consumer_id;consumer_id+;while(toend)Sleep(get);CString str;CString str1;CString str2;WaitForSingleObject(SemaphoreFULL3,INFINITE);WaitForSingleObject(hMutex3,INFINITE);get_buffer3+;str.Format(%s%d%s,本次生產(chǎn)完成:,get_buffer3,次消費);str2.Format(%s%d%s,線程,j,在運行其他線程處于阻塞狀態(tài));m_list_buffer3-GetText(0,getget);m_list_buffer3-DeleteString(0);m_list_consumer-DeleteString(0);m_list_consumer-DeleteString(0);m_list_consumer-InsertString(-1,str);m_list_consumer-InsertString(-1,getget);m_list_consumer-InsertString(-1,str2);Sleep(400);m_list_consumer-DeleteString(2);ReleaseMutex(hMutex3); ReleaseSemaphore(SemaphoreEmpty3,1,NULL);return 1;5.5. 解決的技術難點、經(jīng)常犯的錯誤 (1)不了解MFC已經(jīng)封裝好的函數(shù)的功能,有時候都不會調用,要通過MSDN來查,或者通過百度來查。(2)控件不太會使用,剛開始的時候還不知道如何綁定控件和變量。(3)全局變量和局部變量的使用不清楚,有時候造成一些錯誤。6. 測試時出現(xiàn)的問題及其解決方法 (1)局部變量的運用:有一次有一個局部變量寫錯了,把j寫成了i,結果導致程序運行不下去,我通過單步跟蹤,跟蹤程序的運行,最后修改了這個局部變量。 (2)隨機生產(chǎn)的產(chǎn)品如何記錄:并非記錄全部產(chǎn)生的變量,我在生產(chǎn)者線程中用一個局部變量記錄隨機產(chǎn)生的字符產(chǎn)品,然后將其放入buffer1,搬運者是通過獲取buffer里的第一個字符就是所要搬運的產(chǎn)品。 (3)buffer的內的內容實時顯示是通過在定義了buffer
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 3.1工藝模塊簡介
- 八月十五美容院活動方案
- 公交公司七進活動方案
- 公交客運節(jié)約活動方案
- 小狗和小貓500字(8篇)
- 公眾號策劃活動方案
- 公會協(xié)力活動方案
- 公會趣味活動方案
- 公關公司創(chuàng)意策劃方案
- 公關贊助活動策劃方案
- JG/T 283-2010膨脹?;⒅檩p質砂漿
- 前臺訂機票管理制度
- 浪潮新員工培訓體系大綱
- 2025年7月浙江省普通高中學業(yè)水平考試歷史仿真模擬卷01(含答案)
- 2024福建省閩投深海養(yǎng)殖裝備租賃有限責任公司招聘7人筆試參考題庫附帶答案詳解
- 法人變更交接協(xié)議書
- 地七年級下冊全冊知識要點總復習-2024-2025學年七年級地理教學課件(人教版2024)
- 2024-2025學年部編版四年級語文下冊期末模擬試卷
- 車牌過戶協(xié)議書范本
- 2025年中考歷史考試綱要解讀
- 2025年統(tǒng)編版八年級下冊道德與法治期末復習課件327張
評論
0/150
提交評論