燕山大學(xué)os課程設(shè)計(jì)說(shuō)明書(shū).doc_第1頁(yè)
燕山大學(xué)os課程設(shè)計(jì)說(shuō)明書(shū).doc_第2頁(yè)
燕山大學(xué)os課程設(shè)計(jì)說(shuō)明書(shū).doc_第3頁(yè)
燕山大學(xué)os課程設(shè)計(jì)說(shuō)明書(shū).doc_第4頁(yè)
燕山大學(xué)os課程設(shè)計(jì)說(shuō)明書(shū).doc_第5頁(yè)
已閱讀5頁(yè),還剩12頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

操作系統(tǒng)課設(shè)報(bào)告1. 概述31.1. 目的31.2. 主要完成的任務(wù)31.3. 使用的開(kāi)發(fā)工具31.4. 解決的主要問(wèn)題32. 使用的基本概念和原理32.1. 線程32.2. 線程的同步42.3. 模態(tài)對(duì)話框42.4. 原理43. 總體設(shè)計(jì)43.1. 確定基本的技術(shù)路線43.2. 軟件的總體結(jié)構(gòu)43.3. 創(chuàng)建的進(jìn)程和線程54. 詳細(xì)設(shè)計(jì)54.1. 利用的進(jìn)程操作的函數(shù)、原語(yǔ)、API54.1.1. 信號(hào)量創(chuàng)建函數(shù)54.1.2. 互斥對(duì)象的創(chuàng)建.54.1.3. 線程創(chuàng)建函數(shù)64.1.4. 等待函數(shù)64.2. 模塊內(nèi)部的流程和實(shí)現(xiàn)算法64.3. 全局變量的聲明85. 編碼設(shè)計(jì)95.1. 開(kāi)發(fā)環(huán)境的設(shè)置和建立95.2. 編譯環(huán)境的設(shè)置95.3. 程序設(shè)計(jì)時(shí)要注意的事項(xiàng)105.4. 主要程序的代碼設(shè)計(jì)及注釋105.5. 解決的技術(shù)難點(diǎn)、經(jīng)常犯的錯(cuò)誤146. 測(cè)試時(shí)出現(xiàn)的問(wèn)題及其解決方法147. 軟件使用說(shuō)明及運(yùn)行結(jié)果147.1. 基本功能147.2. 需要運(yùn)行的環(huán)境157.3. 安裝及運(yùn)行157.4. 操作157.5. 運(yùn)行結(jié)果158. 總結(jié)168.1. 操作系統(tǒng)課程設(shè)計(jì)完成情況168.2. 收獲和感受168.3. 經(jīng)驗(yàn)總結(jié)169. 參考文獻(xiàn)171. 概述1.1. 目的 通過(guò)使用程序設(shè)計(jì)語(yǔ)言設(shè)計(jì)一個(gè)程序,模擬生產(chǎn)者消費(fèi)者和搬運(yùn)者對(duì)產(chǎn)品操作的過(guò)程。1.2. 主要完成的任務(wù)PutMove2Buff1Buff2Buff3GetMove1 圖1 Buffer操作 (1) 可以隨機(jī)產(chǎn)生字符數(shù)據(jù),由put操作放入Buff1,buffer中容量單位是字符。 (2) 提供良好圖形界面,顯示Buffer的操作過(guò)程。 (3) 可以設(shè)定各Buffer的容量、PUT、GET、Move操作的個(gè)數(shù); (4) 可以設(shè)定PUT、GET、Move操作的速度; (5) 實(shí)時(shí)顯示每個(gè)Buffer中數(shù)據(jù)的個(gè)數(shù)和數(shù)據(jù)的內(nèi)容,空閑Buffer的空間的個(gè)數(shù); (6) 實(shí)時(shí)顯示線程、進(jìn)程所處于等待(阻塞)狀態(tài)的個(gè)數(shù) (7) 程序運(yùn)行結(jié)束,顯示匯總數(shù)據(jù): 總的運(yùn)行時(shí)間; Buffer中數(shù)據(jù)的個(gè)數(shù); 已放入BUFFER的數(shù)據(jù)個(gè)數(shù); 已放已取的數(shù)據(jù)個(gè)數(shù); 平均每個(gè)buffer中的數(shù)據(jù)個(gè)數(shù)。1.3. 使用的開(kāi)發(fā)工具使用MFC在VC+6.0上完成程序的設(shè)計(jì)。1.4. 解決的主要問(wèn)題 (1)可以隨機(jī)產(chǎn)生字符數(shù)據(jù)。 (2)設(shè)計(jì)put,get,move的線程。 (3)可以設(shè)計(jì)buffer的容量,put,get,move的個(gè)數(shù)。 (4)控制put,get,move的速度。 (5)實(shí)時(shí)顯示buffer的內(nèi)容。2. 使用的基本概念和原理2.1. 線程線程,有時(shí)被稱(chēng)為輕量級(jí)進(jìn)程(Lightweight Process,LWP),是程序執(zhí)行流的最小單元。線程是進(jìn)程中的一個(gè)實(shí)體,是被系統(tǒng)獨(dú)立調(diào)度和分派的基本單位,線程自己不擁有系統(tǒng)資源,只擁有一點(diǎn)在運(yùn)行中必不可少的資源,但它可與同屬一個(gè)進(jìn)程的其它線程共享進(jìn)程所擁有的全部資源。一個(gè)線程可以創(chuàng)建和撤消另一個(gè)線程,同一進(jìn)程中的多個(gè)線程之間可以并發(fā)執(zhí)行。由于線程之間的相互制約,致使線程在運(yùn)行中呈現(xiàn)出間斷性。線程也有就緒、阻塞和運(yùn)行三種基本狀態(tài)。每一個(gè)程序都至少有一個(gè)線程,若程序只有一個(gè)線程,那就是程序本身。2.2. 線程的同步 臨界段:臨界段對(duì)象通過(guò)提供所有線程必須共享的對(duì)象來(lái)控制線程。只有擁有臨界段對(duì)象的線程才可以訪問(wèn)保護(hù)資源(進(jìn)行臨界區(qū)操作)。在另一個(gè)線程可以獲取對(duì)象的訪問(wèn)權(quán)。用戶應(yīng)用程序可能會(huì)使用臨界對(duì)象來(lái)阻止兩個(gè)線程同時(shí)訪問(wèn)共享的資源發(fā)文件等。 互斥量:互斥量的工作方式和臨界段非常相似,其區(qū)別在于互斥量不公保護(hù)一個(gè)進(jìn)程內(nèi)的資源共享,而且還保護(hù)系統(tǒng)中進(jìn)程之間的共享資源。它是通過(guò)為互斥量提供一個(gè)“互斥量名”來(lái)進(jìn)行進(jìn)程間資源共享協(xié)調(diào)的。 事件:事件對(duì)象用于給線程傳遞信號(hào),指示線程中特定的操作可以開(kāi)始或結(jié)束。除非線程已經(jīng)收到了這個(gè)事件信號(hào),否則它將一直處于掛起狀態(tài)。當(dāng)事件對(duì)象進(jìn)入其信號(hào)狀態(tài)時(shí),正在等待該事件的線程就可以開(kāi)始執(zhí)行。例如,一個(gè)應(yīng)用程序可以通過(guò)事件來(lái)通知線程它需要的數(shù)據(jù)已經(jīng)準(zhǔn)備好。經(jīng)常利用事件進(jìn)行線程之間的通信。 信號(hào)量:信號(hào)量與互斥相似,但是互斥只允許在同一時(shí)刻一個(gè)線程訪問(wèn)它的數(shù)據(jù),而信號(hào)量允許多個(gè)線程在同一時(shí)刻訪問(wèn)它的數(shù)據(jù)。WIN32 不知道哪一個(gè)線程擁有信號(hào)量,它只保證信號(hào)量使用的資源計(jì)數(shù)正確的設(shè)置。2.3. 模態(tài)對(duì)話框 模態(tài)對(duì)話框(Modal Dialogue Box,又叫做模式對(duì)話框),是指在用戶想要對(duì)對(duì)話框以外的應(yīng)用程序進(jìn)行操作時(shí),必須首先對(duì)該對(duì)話框進(jìn)行響應(yīng)。如單擊【確定】或【取消】按鈕等將該對(duì)話框關(guān)閉。2.4. 原理 使用信號(hào)量作為同步互斥的工具,通過(guò)對(duì)BUFFER1、BUFFER2的容量,還有控制權(quán)設(shè)置不同的信號(hào)量來(lái)協(xié)調(diào)PUT、GET、MOVE線程,使其同步來(lái)實(shí)現(xiàn)P、V操作。3. 總體設(shè)計(jì)3.1. 確定基本的技術(shù)路線用MFC設(shè)計(jì)的,是面向?qū)ο蟮某绦颉?.2. 軟件的總體結(jié)構(gòu)設(shè)置模塊,設(shè)置生產(chǎn)者消費(fèi)者搬運(yùn)者的初始值,及其它們的速度。顯示模塊,實(shí)時(shí)顯示生產(chǎn)者消費(fèi)者搬運(yùn)者及buffer的情況變化,還有匯總的情況。生產(chǎn)者消費(fèi)者搬運(yùn)者過(guò)程演示控制模塊,控制開(kāi)始,停止及退出。 圖2 框架圖3.3. 創(chuàng)建的進(jìn)程和線程 (1)DWORD WINAPI ThreadProduct(LPVOID lpParameter);/生產(chǎn)者線程 (2)DWORD WINAPI ThreadConsumer(LPVOID lpParameter);/生產(chǎn)者線程 (3)DWORD WINAPI ThreadMover1(LPVOID lpParameter);/搬運(yùn)者1線程 (4)DWORD WINAPI ThreadMover2(LPVOID lpParameter);/搬運(yùn)者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);/時(shí)間的線程4. 詳細(xì)設(shè)計(jì)4.1. 利用的進(jìn)程操作的函數(shù)、原語(yǔ)、API 4.1.1. 信號(hào)量創(chuàng)建函數(shù) HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, / 安全屬性指針LONG lInitialCount, / 初始計(jì)數(shù)LONG lMaximumCount, / 最大計(jì)數(shù)LPCTSTR lpName / 對(duì)象名指針); 該函數(shù)創(chuàng)建一個(gè)信號(hào)量,llnitialCount 是對(duì)信號(hào)量的初始值,iMaximunCount為信號(hào)量的最大值,即信號(hào)量在一個(gè)范圍內(nèi)有效,例empty=:CreateSemaphore(0,0,M,0);第二個(gè)0為empty信號(hào)量的初始值,M為信號(hào)量的最大值,在這個(gè)范圍內(nèi)(0,M)信號(hào)量都是有信號(hào)的。4.1.2. 互斥對(duì)象的創(chuàng)建HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,安全屬性結(jié)構(gòu)指針,可為NULL,表示默認(rèn)安全性BOOL bInitialOwner,/是否占有該互斥量,TRUE:占有,F(xiàn)ALSE:不占有LPCTSTR lpName/設(shè)置互斥對(duì)象的名字);如果一個(gè)線程擁有了一個(gè)互斥對(duì)象后,當(dāng)該線程運(yùn)行完成后就要釋放該互斥對(duì)象,不然其他的線程得不到互斥對(duì)象則無(wú)法運(yùn)行。用ReleaseMutex(HWND);操作它的具體作用是每調(diào)用它一次將互斥對(duì)象的計(jì)數(shù)器減一,直到減到零為止,此時(shí)釋放互斥對(duì)象,并將互斥對(duì)象中的線程id置零。它的使用條件是,互斥對(duì)象在哪個(gè)線程中被創(chuàng)建,就在哪個(gè)線程里面釋放。因?yàn)檎{(diào)用的時(shí)候會(huì)檢查當(dāng)前線程的id是不是與互斥對(duì)象中保存的id一致,若一致,則此次操作有效,不一致,則無(wú)效。4.1.3. 線程創(chuàng)建函數(shù)HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes./線程安全屬性DWORD dwStackSize,/線程堆棧的初始化大小,等于0時(shí)為系統(tǒng)默認(rèn)的堆棧大小PLTHREAD_START_ROUTINE lpStartAddress,/線程函數(shù)LPVOID lpParameter,/線程參數(shù)DWORD dwCreationFlags,/創(chuàng)建方式LPDWORD lpThreadId/線程標(biāo)識(shí)符);該函數(shù)創(chuàng)建一個(gè)線程,如果沒(méi)有特殊需要除第三個(gè)參數(shù)外都可設(shè)為0,按系統(tǒng)的默認(rèn)取值對(duì)待,主要是第三個(gè)參數(shù),它是線程程序的入口,線程序入口的標(biāo)準(zhǔn)形式為 UINT FUNCTION(LPVOID param)線程函數(shù)里可以傳一個(gè)指針做為參數(shù)(param),該參數(shù)由創(chuàng)建線程函數(shù)(CreateThread)里的第四個(gè)參數(shù)確定。4.1.4. 等待函數(shù) DWORD WaitForSingleObjec( HANDLE hHandle,/對(duì)象句柄 DWORD dwMilliseconds/等待的時(shí)間,單位為毫秒 )該函數(shù)在不同的應(yīng)用里會(huì)有不同的意義,在信號(hào)量里應(yīng)用時(shí)主要是判斷信號(hào)量是否有信號(hào)。第二個(gè)參數(shù)為等待時(shí)間,我們通常設(shè)為INFINITE,即為無(wú)限等待,在等待期間會(huì)將線程掛起,直到等待的信號(hào)量有信號(hào)。4.2. 模塊內(nèi)部的流程和實(shí)現(xiàn)算法 設(shè)置6個(gè)信號(hào)量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è)置三類(lèi)進(jìn)程函數(shù),用信號(hào)量實(shí)現(xiàn)同步互斥,PUT,MOVE,GET算法如下: While()P(empty1); /*判斷buff1是否有空間,沒(méi)有則等待 */ P(hMutex1); /*是否可操作buffer1*/PUT; V(hMutex1); /*設(shè)置buff1可操作標(biāo)志 */ V(full1); /*設(shè)置buff1有數(shù)據(jù)的標(biāo)志 */ until false Move1 While()P(full1); /*判斷buffer1是否有數(shù)據(jù)*/P(empty2); /*判斷buffer2是否有空間*/ P(hMutex1); /*是否可操作buffer1 */P(hMutex2); /*是否可操作buffer2 */MOVE; V(hMutex1); /*設(shè)置buffer1可操作標(biāo)志*/ V(hMutex2); /*設(shè)置buffer2可操作標(biāo)志*/ V(empty1); /*設(shè)置buffer1有空間標(biāo)志*/ V(full2); /*設(shè)置buffer2有數(shù)據(jù)標(biāo)志*/ until false Move2 While()P(full2); /*判斷buffer2是否有數(shù)據(jù)*/P(empty3); /*判斷buffer3是否有空間*/ P(hMutex2); /*是否可操作buffer2 */P(hMutex3); /*是否可操作buffer3*/MOVE; V(hMutex2); /*設(shè)置buffer2可操作標(biāo)志*/ V(hMutex3); /*設(shè)置buffer3可操作標(biāo)志*/ V(empty2); /*設(shè)置buffer2有空間標(biāo)志*/ V(full3); /*設(shè)置buffer3有數(shù)據(jù)標(biāo)志*/ until false While()P(full3); /*判斷buffer3是否有數(shù)據(jù),沒(méi)有則等待 */ P(hMutex3); /*是否可操作buffer3*/GET; V(hMutex3); /*設(shè)置buffer3可操作標(biāo)志 */ V(full3); /*設(shè)置buffer3有數(shù)據(jù)的標(biāo)志 */ until false4.3. 全局變量的聲明 int put_buffer1=0;/放入buffer1的產(chǎn)品個(gè)數(shù); int move_buffer1=0;/從buffer1中取走的產(chǎn)品個(gè)數(shù); int move_buffer2=0;/從buffer2中取走的產(chǎn)品個(gè)數(shù); int get_buffer3=0;/從buffer3中取走的產(chǎn)品個(gè)數(shù); int m_time;/記錄時(shí)間 int buffer1;/buffer1中產(chǎn)品個(gè)數(shù) int buffer2;/buffer2中產(chǎn)品個(gè)數(shù) int buffer3;/buffer3中產(chǎn)品個(gè)數(shù) int consumer;/消費(fèi)者個(gè)數(shù) int product;/生產(chǎn)者個(gè)數(shù) int mover;/搬運(yùn)者一的個(gè)數(shù) int mover2;/搬運(yùn)者二的個(gè)數(shù) int producterid=1;/生產(chǎn)者的id號(hào) int moverid1;/搬運(yùn)者1的id號(hào) int moverid2;/搬運(yùn)者2的id號(hào) int consumer_id=1;/消費(fèi)者的id int productid=101;/生產(chǎn)者生產(chǎn)出來(lái)的產(chǎn)品的id號(hào) int name_product;/存儲(chǔ)隨機(jī)產(chǎn)品; int ioend=0;/判斷用的 int toend=1; int consumerid=101;/消費(fèi)者消費(fèi)的產(chǎn)品id號(hào) int move1_consumerid=101;/搬運(yùn)者搬運(yùn)的產(chǎn)品的id號(hào) 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. 編碼設(shè)計(jì)5.1. 開(kāi)發(fā)環(huán)境的設(shè)置和建立 (1)起動(dòng)VISUAL C+ 6.0程序 (2)在菜單里選擇文件,子菜單里選擇新建,彈出新建對(duì)話框,如圖3所示。 圖3.新建工程 (3)在左邊的新建選項(xiàng)里選擇MFC AppWizardexe選項(xiàng),右邊的project name里填入一個(gè)工程名,選擇OK按扭。選擇默認(rèn)設(shè)置。5.2. 編譯環(huán)境的設(shè)置 在WINDOWS環(huán)境下的多線程中,為保證程序的正確性,必須使用用于多線程環(huán)境的正確的函數(shù)庫(kù),在VC+ 6.0開(kāi)發(fā)環(huán)境中在菜單工程中設(shè)置中進(jìn)行選擇。步驟如下: (1)選擇PROJECT菜單中的SETTING.項(xiàng); (2)在打開(kāi)的表彰中選擇C/C+項(xiàng); (3)選擇CATEGORY中的CODE GENERATION項(xiàng); (4)在USE RUN-TIME LIBRARY中選擇MULTITHREADED; (5)單擊OK即可。 此時(shí),在命令行方式下編譯選項(xiàng)由ML變?yōu)镸T,如圖4所示。 圖4.編譯環(huán)境5.3. 程序設(shè)計(jì)時(shí)要注意的事項(xiàng)(1)盡量避免全局變量的使用;(2)變量的命名要規(guī)范;(3)注意給代碼多寫(xiě)注釋?zhuān)?4)注意進(jìn)行模塊化設(shè)計(jì),寫(xiě)相應(yīng)的函數(shù)來(lái)完成相應(yīng)的功能。5.4. 主要程序的代碼設(shè)計(jì)及注釋 (1)四個(gè)主要線程PUT,GET,MOVE1,MOVE2代碼實(shí)現(xiàn)。DWORD WINAPI ThreadProduct(LPVOID lpParameter)int j=producterid;/用j來(lái)標(biāo)記第幾條線程;producterid+;while(toend)Sleep(put);CString str;CString str1;CString str2;WaitForSingleObject(SemaphoreEmpty,INFINITE);WaitForSingleObject(hMutex,INFINITE);put_buffer1+;/放進(jìn)去一個(gè)產(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)品號(hào):,productid+,產(chǎn)品名:,name_product);str2.Format(%s%d%s,線程,j,在運(yùn)行,其他線程處于阻塞狀態(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)品個(gè)數(shù);str.Format(%s%d%s%4d%s,搬運(yùn)者,j,buffer1-buffer2,move_buffer1,次搬運(yùn));str2.Format(%s%d%s,線程,j,在運(yùn)行其他線程處于阻塞狀態(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)品個(gè)數(shù);str.Format(%s%d%s%4d%s,搬運(yùn)者,j,buffer2-buffer3,move_buffer2,次搬運(yùn));str2.Format(%s%d%s,線程,j,在運(yùn)行其他線程處于阻塞狀態(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,次消費(fèi));str2.Format(%s%d%s,線程,j,在運(yùn)行其他線程處于阻塞狀態(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. 解決的技術(shù)難點(diǎn)、經(jīng)常犯的錯(cuò)誤 (1)不了解MFC已經(jīng)封裝好的函數(shù)的功能,有時(shí)候都不會(huì)調(diào)用,要通過(guò)MSDN來(lái)查,或者通過(guò)百度來(lái)查。(2)控件不太會(huì)使用,剛開(kāi)始的時(shí)候還不知道如何綁定控件和變量。(3)全局變量和局部變量的使用不清楚,有時(shí)候造成一些錯(cuò)誤。6. 測(cè)試時(shí)出現(xiàn)的問(wèn)題及其解決方法 (1)局部變量的運(yùn)用:有一次有一個(gè)局部變量寫(xiě)錯(cuò)了,把j寫(xiě)成了i,結(jié)果導(dǎo)致程序運(yùn)行不下去,我通過(guò)單步跟蹤,跟蹤程序的運(yùn)行,最后修改了這個(gè)局部變量。 (2)隨機(jī)生產(chǎn)的產(chǎn)品如何記錄:并非記錄全部產(chǎn)生的變量,我在生產(chǎn)者線程中用一個(gè)局部變量記錄隨機(jī)產(chǎn)生的字符產(chǎn)品,然后將其放入buffer1,搬運(yùn)者是通過(guò)獲取buffer里的第一個(gè)字符就是所要搬運(yùn)的產(chǎn)品。 (3)buffer的內(nèi)的內(nèi)容實(shí)時(shí)顯示是通過(guò)在定義了buffer

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論