版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
操作系統(tǒng)課程設(shè)計(jì)實(shí)驗(yàn)報(bào)告目錄實(shí)驗(yàn)一 3一、 實(shí)驗(yàn)題目 3二、 實(shí)驗(yàn)?zāi)康?3三、 總體設(shè)計(jì) 3四、 詳細(xì)設(shè)計(jì) 6五、 實(shí)驗(yàn)結(jié)果與分析 10六、 小結(jié)與心得體會(huì) 14實(shí)驗(yàn)二 15一、 實(shí)驗(yàn)題目 15二、 實(shí)驗(yàn)?zāi)康?15三、 總體設(shè)計(jì) 15四、 詳細(xì)設(shè)計(jì) 16五、 實(shí)驗(yàn)結(jié)果與分析 19六、 小結(jié)與心得體會(huì) 20實(shí)驗(yàn)三 21一、 實(shí)驗(yàn)題目 21二、 實(shí)驗(yàn)?zāi)康?21三、 總體設(shè)計(jì) 21四、 詳細(xì)設(shè)計(jì) 21五、 實(shí)驗(yàn)結(jié)果與分析 26六、 小結(jié)與心得體會(huì) 28實(shí)驗(yàn)四 29一、 實(shí)驗(yàn)題目 29二、 實(shí)驗(yàn)?zāi)康?29三、 總體設(shè)計(jì) 29四、 詳細(xì)設(shè)計(jì) 29五、 實(shí)驗(yàn)結(jié)果與分析 34六、 小結(jié)與心得體會(huì) 35實(shí)驗(yàn)五 36一、 實(shí)驗(yàn)題目 36二、 實(shí)驗(yàn)?zāi)康?36三、 總體設(shè)計(jì) 36四、 詳細(xì)設(shè)計(jì) 41五、 實(shí)驗(yàn)結(jié)果與分析 44六、 小結(jié)與心得體會(huì) 53實(shí)驗(yàn)六 54一、 實(shí)驗(yàn)題目 54二、 實(shí)驗(yàn)?zāi)康?54三、 總體設(shè)計(jì) 54四、 詳細(xì)設(shè)計(jì) 54五、 實(shí)驗(yàn)結(jié)果與分析 61六、 小結(jié)與心得體會(huì) 62實(shí)驗(yàn)七 63一、 實(shí)驗(yàn)題目 63二、 實(shí)驗(yàn)?zāi)康?63三、 總體設(shè)計(jì) 63四、 詳細(xì)設(shè)計(jì) 68五、 實(shí)驗(yàn)結(jié)果與分析 70六、 小結(jié)與心得體會(huì) 71實(shí)驗(yàn)八 72一、 實(shí)驗(yàn)題目 72二、 實(shí)驗(yàn)?zāi)康?72三、 總體設(shè)計(jì) 72四、 詳細(xì)設(shè)計(jì) 76五、 實(shí)驗(yàn)結(jié)果與分析 79六、 小結(jié)與心得體會(huì) 80
實(shí)驗(yàn)一實(shí)驗(yàn)題目實(shí)驗(yàn)一Windows進(jìn)程管理實(shí)驗(yàn)?zāi)康膶W(xué)會(huì)使用VC編寫基本的Win32ConsolApplication(控制臺(tái)應(yīng)用程序)。通過創(chuàng)建進(jìn)程、觀察正在運(yùn)行的進(jìn)程和終止進(jìn)程的程序設(shè)計(jì)和調(diào)試操作,進(jìn)一步熟悉操作系統(tǒng)的進(jìn)程概念,理解Windows進(jìn)程的“一生”。通過閱讀和分析實(shí)驗(yàn)程序,學(xué)習(xí)創(chuàng)建進(jìn)程、觀察進(jìn)程、終止進(jìn)程以及父子進(jìn)程同步的基本程序設(shè)計(jì)方法??傮w設(shè)計(jì)背景知識(shí)Windows所創(chuàng)建的每個(gè)進(jìn)程都從調(diào)用CreateProcess()API函數(shù)開始,該函數(shù)的任務(wù)是在對(duì)象管理器子系統(tǒng)內(nèi)初始化進(jìn)程對(duì)象。每一進(jìn)程都以調(diào)用ExitProcess()或TerminateProcess()API函數(shù)終止。通常應(yīng)用程序的框架負(fù)責(zé)調(diào)用ExitProcess()函數(shù)。對(duì)于C++運(yùn)行庫來說,這一調(diào)用發(fā)生在應(yīng)用程序的main()函數(shù)返回之后。創(chuàng)建進(jìn)程CreateProcess()調(diào)用的核心參數(shù)是可執(zhí)行文件運(yùn)行時(shí)的文件名及其命令行。表1-1詳細(xì)地列出了每個(gè)參數(shù)的類型和名稱??梢灾付ǖ谝粋€(gè)參數(shù),即應(yīng)用程序的名稱,其中包括相對(duì)于當(dāng)前進(jìn)程的當(dāng)前目錄的全路徑或者利用搜索方法找到的路徑;lpCommandLine參數(shù)允許調(diào)用者向新應(yīng)用程序發(fā)送數(shù)據(jù);接下來的三個(gè)參數(shù)與進(jìn)程和它的主線程以及返回的指向該對(duì)象的句柄的安全性有關(guān)。然后是標(biāo)志參數(shù),用以在dwCreationFlags參數(shù)中指明系統(tǒng)應(yīng)該給予新進(jìn)程什么行為。經(jīng)常使用的標(biāo)志是CREATE_SUSPNDED,告訴主線程立刻暫停。當(dāng)準(zhǔn)備好時(shí),應(yīng)該使用ResumeThread()API來啟動(dòng)進(jìn)程。另一個(gè)常用的標(biāo)志是CREATE_NEW_CONSOLE,告訴新進(jìn)程啟動(dòng)自己的控制臺(tái)窗口,而不是利用父窗口。這一參數(shù)還允許設(shè)置進(jìn)程的優(yōu)先級(jí),用以向系統(tǒng)指明,相對(duì)于系統(tǒng)中所有其他的活動(dòng)進(jìn)程來說,給此進(jìn)程多少CPU時(shí)間。接著是CreateProcess()函數(shù)調(diào)用所需要的三個(gè)通常使用缺省值的參數(shù)。第一個(gè)參數(shù)是lpEnvironment參數(shù),指明為新進(jìn)程提供的環(huán)境;第二個(gè)參數(shù)是lpCurrentDirectory,可用于向主創(chuàng)進(jìn)程發(fā)送與缺省目錄不同的新進(jìn)程使用的特殊的當(dāng)前目錄;第三個(gè)參數(shù)是STARTUPINFO數(shù)據(jù)結(jié)構(gòu)所必需的,用于在必要時(shí)指明新應(yīng)用程序的主窗口的外觀。CreateProcess()的最后一個(gè)參數(shù)是用于新進(jìn)程對(duì)象及其主線程的句柄和ID的返回值緩沖區(qū)。以PROCESS_INFORMATION結(jié)構(gòu)中返回的句柄調(diào)用CloseHandle()API函數(shù)是重要的,因?yàn)槿绻粚⑦@些句柄關(guān)閉的話,有可能危及主創(chuàng)進(jìn)程終止之前的任何未釋放的資源。正在運(yùn)行的進(jìn)程如果一個(gè)進(jìn)程擁有至少一個(gè)執(zhí)行線程,則為正在系統(tǒng)中運(yùn)行的進(jìn)程。通常,這種進(jìn)程使用主線程來指示它的存在。當(dāng)主線程結(jié)束時(shí),調(diào)用ExitProcess()API函數(shù),通知系統(tǒng)終止它所擁有的所有正在運(yùn)行、準(zhǔn)備運(yùn)行或正在掛起的其他線程。當(dāng)進(jìn)程正在運(yùn)行時(shí),可以查看它的許多特性,其中少數(shù)特性也允許加以修改。首先可查看的進(jìn)程特性是系統(tǒng)進(jìn)程標(biāo)識(shí)符(PID),可利用GetCurrentProcessId()API函數(shù)來查看,與GetCurrentProcess()相似,對(duì)該函數(shù)的調(diào)用不能失敗,但返回的PID在整個(gè)系統(tǒng)中都可使用。其他的可顯示當(dāng)前進(jìn)程信息的API函數(shù)還有GetStartupInfo()和GetProcessShutdownParameters(),可給出進(jìn)程存活期內(nèi)的配置詳情。通常,一個(gè)進(jìn)程需要它的運(yùn)行期環(huán)境的信息。例如API函數(shù)GetModuleFileName()和GetCommandLine(),可以給出用在CreateProcess()中的參數(shù)以啟動(dòng)應(yīng)用程序。在創(chuàng)建應(yīng)用程序時(shí)可使用的另一個(gè)API函數(shù)是IsDebuggerPresent()。可利用API函數(shù)GetGuiResources()來查看進(jìn)程的GUI資源。此函數(shù)既可返回指定進(jìn)程中的打開的GUI對(duì)象的數(shù)目,也可返回指定進(jìn)程中打開的USER對(duì)象的數(shù)目。進(jìn)程的其他性能信息可通過GetProcessIoCounters()、GetProcessPriorityBoost()、GetProcessTimes()和GetProcessWorkingSetSize()API得到。以上這幾個(gè)API函數(shù)都只需要具有PROCESS_QUERY_INFORMATION訪問權(quán)限的指向所感興趣進(jìn)程的句柄。另一個(gè)可用于進(jìn)程信息查詢的API函數(shù)是GetProcessVersion()。此函數(shù)只需感興趣進(jìn)程的PID(進(jìn)程標(biāo)識(shí)號(hào))。這一API函數(shù)與GetVersionEx()的共同作用,可確定運(yùn)行進(jìn)程的系統(tǒng)的版本號(hào)。終止進(jìn)程所有進(jìn)程都是以調(diào)用ExitProcess()或者TerminateProcess()函數(shù)結(jié)束的。但最好使用前者而不要使用后者,因?yàn)檫M(jìn)程是在完成了它的所有的關(guān)閉“職責(zé)”之后以正常的終止方式來調(diào)用前者的。而外部進(jìn)程通常調(diào)用后者即突然終止進(jìn)程的進(jìn)行,由于關(guān)閉時(shí)的途徑不太正常,有可能引起錯(cuò)誤的行為。TerminateProcess()API函數(shù)只要打開帶有PROCESS_TERMINATE訪問權(quán)的進(jìn)程對(duì)象,就可以終止進(jìn)程,并向系統(tǒng)返回指定的代碼。這是一種“野蠻”的終止進(jìn)程的方式,但是有時(shí)卻是需要的。如果開發(fā)人員確實(shí)有機(jī)會(huì)來設(shè)計(jì)“謀殺”(終止別的進(jìn)程的進(jìn)程)和“受害”進(jìn)程(被終止的進(jìn)程)時(shí),應(yīng)該創(chuàng)建一個(gè)進(jìn)程間通訊的內(nèi)核對(duì)象——如一個(gè)互斥程序——這樣一來,“受害”進(jìn)程只在等待或周期性地測試它是否應(yīng)該終止。進(jìn)程同步Windows提供的常用對(duì)象可分成三類:核心應(yīng)用服務(wù)、線程同步和線程間通訊。其中,開發(fā)人員可以使用線程同步對(duì)象來協(xié)調(diào)線程和進(jìn)程的工作,以使其共享信息并執(zhí)行任務(wù)。此類對(duì)象包括互鎖數(shù)據(jù)、臨界段、事件、互斥體和信號(hào)等。多線程編程中關(guān)鍵的一步是保護(hù)所有的共享資源,工具主要有互鎖函數(shù)、臨界段和互斥體等;另一個(gè)實(shí)質(zhì)性部分是協(xié)調(diào)線程使其完成應(yīng)用程序的任務(wù),為此,可利用內(nèi)核中的事件對(duì)象和信號(hào)。在進(jìn)程內(nèi)或進(jìn)程間實(shí)現(xiàn)線程同步的最方便的方法是使用事件對(duì)象,這一組內(nèi)核對(duì)象允許一個(gè)線程對(duì)其受信狀態(tài)進(jìn)行直接控制。而互斥體則是另一個(gè)可命名且安全的內(nèi)核對(duì)象,其主要目的是引導(dǎo)對(duì)共享資源的訪問。擁有單一訪問資源的線程創(chuàng)建互斥體,所有想要訪問該資源的線程應(yīng)該在實(shí)際執(zhí)行操作之前獲得互斥體,而在訪問結(jié)束時(shí)立即釋放互斥體,以允許下一個(gè)等待線程獲得互斥體,然后接著進(jìn)行下去。與事件對(duì)象類似,互斥體容易創(chuàng)建、打開、使用并清除。利用CreateMutex()API可創(chuàng)建互斥體,創(chuàng)建時(shí)還可以指定一個(gè)初始的擁有權(quán)標(biāo)志,通過使用這個(gè)標(biāo)志,只有當(dāng)線程完成了資源的所有的初始化工作時(shí),才允許創(chuàng)建線程釋放互斥體。為了獲得互斥體,首先,想要訪問調(diào)用的線程可使用OpenMutex()API來獲得指向?qū)ο蟮木浔?;然后,線程將這個(gè)句柄提供給一個(gè)等待函數(shù)。當(dāng)內(nèi)核將互斥體對(duì)象發(fā)送給等待線程時(shí),就表明該線程獲得了互斥體的擁有權(quán)。當(dāng)線程獲得擁有權(quán)時(shí),線程控制了對(duì)共享資源的訪問——必須設(shè)法盡快地放棄互斥體。放棄共享資源時(shí)需要在該對(duì)象上調(diào)用ReleaseMute()API。然后系統(tǒng)負(fù)責(zé)將互斥體擁有權(quán)傳遞給下一個(gè)等待著的線程(由到達(dá)時(shí)間決定順序)。編寫基本的Win32ConsolApplication步驟1:登錄進(jìn)入Windows系統(tǒng),啟動(dòng)VC++6.0。步驟2:在“FILE”菜單中單擊“NEW”子菜單,在“projects”選項(xiàng)卡中選擇“Win32ConsolApplication”,然后在“Projectname”處輸入工程名,在“Location”處輸入工程目錄。創(chuàng)建一個(gè)新的控制臺(tái)應(yīng)用程序工程。步驟3:在“FILE”菜單中單擊“NEW”子菜單,在“Files”選項(xiàng)卡中選擇“C++SourceFile”,然后在“File”處輸入C/C++源程序的文件名。步驟4:將清單1-1所示的程序清單復(fù)制到新創(chuàng)建的C/C++源程序中。編譯成可執(zhí)行文件。步驟5:在“開始”菜單中單擊“程序”-“附件”-“命令提示符”命令,進(jìn)入Windows“命令提示符”窗口,然后進(jìn)入工程目錄中的debug子目錄,執(zhí)行編譯好的可執(zhí)行程序,列出運(yùn)行結(jié)果(如果運(yùn)行不成功,則可能的原因是什么?)創(chuàng)建進(jìn)程本實(shí)驗(yàn)顯示了創(chuàng)建子進(jìn)程的基本框架。該程序只是再一次地啟動(dòng)自身,顯示它的系統(tǒng)進(jìn)程ID和它在進(jìn)程列表中的位置。步驟1:創(chuàng)建一個(gè)“Win32ConsolApplication”工程,然后拷貝清單1-2中的程序,編譯成可執(zhí)行文件。步驟2:在“命令提示符”窗口運(yùn)行步驟1中生成的可執(zhí)行文件,列出運(yùn)行結(jié)果。按下ctrl+alt+del,調(diào)用windows的任務(wù)管理器,記錄進(jìn)程相關(guān)的行為屬性。步驟3:在“命令提示符”窗口加入?yún)?shù)重新運(yùn)行生成的可執(zhí)行文件,列出運(yùn)行結(jié)果。按下ctrl+alt+del,調(diào)用windows的任務(wù)管理器,記錄進(jìn)程相關(guān)的行為屬性。步驟4:修改清單1-2中的程序,將nClone的定義和初始化方法按程序注釋中的修改方法進(jìn)行修改,編譯成可執(zhí)行文件(執(zhí)行前請(qǐng)先保存已經(jīng)完成的工作)。再按步驟2中的方式運(yùn)行,看看結(jié)果會(huì)有什么不一樣。列出行結(jié)果。從中你可以得出什么結(jié)論?說明nClone的作用。變量的定義和初始化方法(位置)對(duì)程序的執(zhí)行結(jié)果有影響嗎?為什么?父子進(jìn)程的簡單通信及終止進(jìn)程步驟1:創(chuàng)建一個(gè)“Win32ConsolApplication”工程,然后拷貝清單1-3中的程序,編譯成可執(zhí)行文件。步驟2:在VC的工具欄單擊“ExecuteProgram”(執(zhí)行程序)按鈕,或者按Ctrl+F5鍵,或者在“命令提示符”窗口運(yùn)行步驟1中生成的可執(zhí)行文件,列出運(yùn)行結(jié)果。步驟3:按源程序中注釋中的提示,修改源程序1-3,編譯執(zhí)行(執(zhí)行前請(qǐng)先保存已經(jīng)完成的工作),列出運(yùn)行結(jié)果。在程序中加入跟蹤語句,或調(diào)試運(yùn)行程序,同時(shí)參考MSDN中的幫助文件CreateProcess()的使用方法,理解父子進(jìn)程如何傳遞參數(shù)。給出程序執(zhí)行過程的大概描述。步驟4:按源程序中注釋中的提示,修改源程序1-3,編譯執(zhí)行,列出運(yùn)行結(jié)果。步驟5:參考MSDN中的幫助文件CreateMutex()、OpenMutex()、ReleaseMutex()和WaitForSingleObject()的使用方法,理解父子進(jìn)程如何利用互斥體進(jìn)行同步的。給出父子進(jìn)程同步過程的一個(gè)大概描述。詳細(xì)設(shè)計(jì)關(guān)鍵代碼清單1-1一個(gè)簡單的Windows控制臺(tái)應(yīng)用程序//hello項(xiàng)目#include"stdafx.h"#include<iostream>voidmain(){std::cout<<"Hello,Win32ConsolApplication"<<std::endl;}清單1-2創(chuàng)建子進(jìn)程#define_CRT_SECURE_NO_WARNINGS#include"stdafx.h"#include<windows.h>#include<iostream>#include<stdio.h>//創(chuàng)建傳遞過來的進(jìn)程的克隆過程并賦于其ID值voidStartClone(intnCloneID){//提取用于當(dāng)前可執(zhí)行文件的文件名TCHARszFilename[MAX_PATH];GetModuleFileName(NULL,szFilename,MAX_PATH);//格式化用于子進(jìn)程的命令行并通知其EXE文件名和克隆IDTCHARszCmdLine[MAX_PATH];sprintf_s(szCmdLine,"\"%s\"%d",szFilename,nCloneID);//用于子進(jìn)程的STARTUPINFO結(jié)構(gòu)STARTUPINFOsi;ZeroMemory(&si,sizeof(si));si.cb=sizeof(si);//必須是本結(jié)構(gòu)的大小//返回的用于子進(jìn)程的進(jìn)程信息PROCESS_INFORMATIONpi;//利用同樣的可執(zhí)行文件和命令行創(chuàng)建進(jìn)程,并賦于其子進(jìn)程的性質(zhì)BOOLbCreateOK=::CreateProcess(szFilename,//產(chǎn)生這個(gè)EXE的應(yīng)用程序的名稱szCmdLine,//告訴其行為像一個(gè)子進(jìn)程的標(biāo)志NULL,//缺省的進(jìn)程安全性NULL,//缺省的線程安全性FALSE,//不繼承句柄CREATE_NEW_CONSOLE,//使用新的控制臺(tái)NULL,//新的環(huán)境NULL,//當(dāng)前目錄&si,//啟動(dòng)信息&pi);//返回的進(jìn)程信息//對(duì)子進(jìn)程釋放引用if(bCreateOK){CloseHandle(pi.hProcess);CloseHandle(pi.hThread);}}intmain(intargc,char*argv[]){//確定派生出幾個(gè)進(jìn)程,及派生進(jìn)程在進(jìn)程列表中的位置intnClone=0;//修改語句:intnClone;//第一次修改:nClone=0;if(argc>1){//從第二個(gè)參數(shù)中提取克隆ID::sscanf_s(argv[1],"%d",&nClone);}//第二次修改:nClone=0;//顯示進(jìn)程位置std::cout<<"ProcessID:"<<::GetCurrentProcessId()<<",CloneID:"<<nClone<<std::endl;//檢查是否有創(chuàng)建子進(jìn)程的需要constintc_nCloneMax=5;if(nClone<c_nCloneMax){//發(fā)送新進(jìn)程的命令行和克隆號(hào)StartClone(++nClone);}//等待響應(yīng)鍵盤輸入結(jié)束進(jìn)程getchar();return0;}清單1-3父子進(jìn)程的簡單通信及終止進(jìn)程的示例程序#include"stdafx.h"#include<windows.h>#include<iostream>#include<stdio.h>staticLPCTSTRg_szMutexName="w2kdg.ProcTerm.mutex.Suicide";//創(chuàng)建當(dāng)前進(jìn)程的克隆進(jìn)程的簡單方法voidStartClone(){//提取當(dāng)前可執(zhí)行文件的文件名TCHARszFilename[MAX_PATH];GetModuleFileName(NULL,szFilename,MAX_PATH);//格式化用于子進(jìn)程的命令行,字符串“child”將作為形參傳遞給子進(jìn)程的main函數(shù)TCHARszCmdLine[MAX_PATH];//實(shí)驗(yàn)1-3步驟3:將下句中的字符串child改為別的字符串,重新編譯執(zhí)行,執(zhí)行前請(qǐng)先保存已經(jīng)完成的工作sprintf_s(szCmdLine,"\"%s\"child",szFilename);//子進(jìn)程的啟動(dòng)信息結(jié)構(gòu)STARTUPINFOsi;ZeroMemory(&si,sizeof(si));si.cb=sizeof(si);//應(yīng)當(dāng)是此結(jié)構(gòu)的大小//返回的用于子進(jìn)程的進(jìn)程信息PROCESS_INFORMATIONpi;//用同樣的可執(zhí)行文件名和命令行創(chuàng)建進(jìn)程,并指明它是一個(gè)子進(jìn)程BOOLbCreateOK=CreateProcess(szFilename,//產(chǎn)生的應(yīng)用程序的名稱(本EXE文件)szCmdLine,//告訴我們這是一個(gè)子進(jìn)程的標(biāo)志NULL,//用于進(jìn)程的缺省的安全性NULL,//用于線程的缺省安全性FALSE,//不繼承句柄CREATE_NEW_CONSOLE,//創(chuàng)建新窗口NULL,//新環(huán)境NULL,//當(dāng)前目錄&si,//啟動(dòng)信息結(jié)構(gòu)&pi);//返回的進(jìn)程信息//釋放指向子進(jìn)程的引用if(bCreateOK){CloseHandle(pi.hProcess);CloseHandle(pi.hThread);}}voidParent(){//創(chuàng)建“自殺”互斥程序體HANDLEhMutexSuicide=CreateMutex(NULL,//缺省的安全性TRUE,//最初擁有的g_szMutexName);//互斥體名稱if(hMutexSuicide!=NULL){//創(chuàng)建子進(jìn)程std::cout<<"Creatingthechildprocess."<<std::endl;StartClone();//指令子進(jìn)程“殺”掉自身std::cout<<"Tellingthechildprocesstoquit."<<std::endl;//等待父進(jìn)程的鍵盤響應(yīng)getchar();//釋放互斥體的所有權(quán),這個(gè)信號(hào)會(huì)發(fā)送給子進(jìn)程的WaitForSingleObject過程ReleaseMutex(hMutexSuicide);//std::cout<<"222"<<std::endl;//消除句柄CloseHandle(hMutexSuicide);}}voidChild(){//打開“自殺”互斥體HANDLEhMutexSuicide=OpenMutex(SYNCHRONIZE,//打開用于同步FALSE,//不需要向下傳遞g_szMutexName);//名稱//std::cout<<"111"<<std::endl;if(hMutexSuicide!=NULL){//報(bào)告我們正在等待指令std::cout<<"Childwaitingforsuicideinstructions."<<std::endl;//子進(jìn)程進(jìn)入阻塞狀態(tài),等待父進(jìn)程通過互斥體發(fā)來的信號(hào)//WaitForSingleObject(hMutexSuicide,INFINITE);WaitForSingleObject(hMutexSuicide,0);//實(shí)驗(yàn)1-3步驟4:將上句改為WaitForSingleObject(hMutexSuicide,0),重新編譯執(zhí)行//準(zhǔn)備好終止,清除句柄std::cout<<"Childquiting."<<std::endl;CloseHandle(hMutexSuicide);}}intmain(intargc,char*argv[]){//決定其行為是父進(jìn)程還是子進(jìn)程if(argc>1&&::strcmp(argv[1],"child")==0){Sleep(1000);Child();}else{Sleep(1000);Parent();}return0;}實(shí)驗(yàn)結(jié)果與分析編寫基本的Win32ConsolApplication步驟5:運(yùn)行不成功可能的原因有:雙引號(hào)是全角符號(hào),需改成半角符號(hào)。創(chuàng)建進(jìn)程步驟2:步驟3:步驟4:nClone初始化的地方不同,程序執(zhí)行的次數(shù)也不同,在判斷有無命令行參數(shù)之前初始化的話程序只執(zhí)行規(guī)定的最多的次數(shù);之后初始化的話就會(huì)無限創(chuàng)建新進(jìn)程。由此得出變量的定義和初始化方法(位置)對(duì)程序的執(zhí)行結(jié)果有影響,因?yàn)橹虚g多了一個(gè)判斷命令行參數(shù)的代碼段,這一段代碼會(huì)更改nClone的值。父子進(jìn)程的簡單通信及終止進(jìn)程步驟2:步驟3:程序判斷有無命令行參數(shù)以及參數(shù)是不是child是的話就開啟子進(jìn)程,否則就開啟父進(jìn)程。父進(jìn)程在執(zhí)行克隆的時(shí)候給自身加上一把鎖從而保證自身是線程安全的函數(shù),同時(shí)在CreateProcess的第二個(gè)參數(shù)傳入child參數(shù),保證下次執(zhí)行的是子進(jìn)程,如此循環(huán),使得父子進(jìn)程能夠并發(fā)進(jìn)行,實(shí)現(xiàn)父子進(jìn)程的通信。步驟4:步驟5: CreateMutex作用是找出當(dāng)前系統(tǒng)是否已經(jīng)存在指定進(jìn)程的實(shí)例,如果沒有則創(chuàng)建一個(gè)互斥體;OpenMutex函數(shù)為現(xiàn)有的一個(gè)已命名互斥體對(duì)象創(chuàng)建一個(gè)新句柄;ReleaseMutex是一種線性指令,具有釋放線程擁有的互斥體的控制權(quán);WaitForSingleObject函數(shù)用來檢測hHandle事件的信號(hào)狀態(tài)。由父進(jìn)程創(chuàng)建一把鎖后,子進(jìn)程不用創(chuàng)建鎖,用的時(shí)候只需要打開就行,保證同一個(gè)時(shí)間段只能有父進(jìn)程或者子進(jìn)程在運(yùn)行。小結(jié)與心得體會(huì)變量的定義和初始化的位置很重要,因此在進(jìn)行程序設(shè)計(jì)的時(shí)候需要設(shè)置好變量的位置,否則會(huì)出現(xiàn)意想不到的問題。
實(shí)驗(yàn)二實(shí)驗(yàn)題目實(shí)驗(yàn)二Linux進(jìn)程管理實(shí)驗(yàn)?zāi)康耐ㄟ^進(jìn)程的創(chuàng)建、撤銷和運(yùn)行加深對(duì)進(jìn)程概念和進(jìn)程并發(fā)執(zhí)行的理解,明確進(jìn)程和程序之間的區(qū)別??傮w設(shè)計(jì)進(jìn)程的創(chuàng)建任務(wù)要求:編寫一段程序,使用系統(tǒng)調(diào)用fork()創(chuàng)建兩個(gè)子進(jìn)程。當(dāng)此程序運(yùn)行時(shí),在系統(tǒng)中有一個(gè)父進(jìn)程和兩個(gè)子進(jìn)程活動(dòng)。讓每一個(gè)進(jìn)程在屏幕上顯示一個(gè)字符:父進(jìn)程顯示字符“a”;兩子進(jìn)程分別顯示字符“b”和字符“c”。試觀察記錄20次運(yùn)行該程序在屏幕上的顯示結(jié)果,并分析原因。步驟1:使用vi或gedit新建一個(gè)forkdemo.c程序,然后拷貝清單2-1中的程序,使用cc或者gcc編譯成可執(zhí)行文件forkdemo。例如,可以使用gcc–oforkdemoforkdemo.c完成編譯。步驟2:在命令行輸入./fork_demo運(yùn)行該程序。步驟3:觀察記錄20次運(yùn)行該程序在屏幕上的顯示結(jié)果,并分析。子進(jìn)程執(zhí)行新任務(wù)任務(wù)要求:編寫一段程序,使用系統(tǒng)調(diào)用fork()創(chuàng)建一個(gè)子進(jìn)程。子進(jìn)程通過系統(tǒng)調(diào)用exec更換自己原有的執(zhí)行代碼,轉(zhuǎn)去執(zhí)行Linux命令/bin/ls(顯示當(dāng)前目錄的列表),然后調(diào)用exit()函數(shù)結(jié)束。父進(jìn)程則調(diào)用waitpid()等待子進(jìn)程結(jié)束,并在子進(jìn)程結(jié)束后顯示子進(jìn)程的標(biāo)識(shí)符,然后正常結(jié)束。步驟1:使用vi或gedit新建一個(gè)exec_demo.c程序,然后拷貝清單2-2中的程序(該程序的執(zhí)行如圖2-1所示),使用cc或者gcc編譯成可執(zhí)行文件exec_demo。例如,可以使用gcc–oexec_demoexec_demo.c完成編譯。步驟2:在命令行輸入./exec_demo運(yùn)行該程序。步驟3:觀察該程序在屏幕上的顯示結(jié)果,并分析。實(shí)現(xiàn)一個(gè)簡單的shell(命令行解釋器)(此任務(wù)有一點(diǎn)難度,可選做)。你的shell類似于sh,bash,csh等,必須支持以下內(nèi)部命令:cd<目錄>更改當(dāng)前的工作目錄到另一個(gè)<目錄>。如果<目錄>未指定,輸出當(dāng)前工作目錄。如果<目錄>不存在,應(yīng)當(dāng)有適當(dāng)?shù)腻e(cuò)誤信息提示。這個(gè)命令應(yīng)該也能改變PWD的環(huán)境變量。environ列出所有環(huán)境變量字符串的設(shè)置(類似于Unix系統(tǒng)下的env命令)。echo<內(nèi)容>顯示echo后的內(nèi)容且換行help簡短概要的輸出你的shell的使用方法和基本功能。jobs輸出shell當(dāng)前的一系列子進(jìn)程,必須提供子進(jìn)程的命名和PID號(hào)。quit,exit,bye退出shell。提示:shell的主體就是反復(fù)下面的循環(huán)過程while(1){接收用戶輸入的命令行;解析命令行;if(用戶命令為內(nèi)部命令)直接處理;elseif(用戶命令為外部命令)創(chuàng)建子進(jìn)程執(zhí)行命令;//參考清單2-2else提示錯(cuò)誤的命令;}詳細(xì)設(shè)計(jì)關(guān)鍵代碼清單2-1創(chuàng)建進(jìn)程intmain(){intx;while((x=fork())==-1);if(x==0)printf("a");elseprintf("b");printf("c");}清單2-2子進(jìn)程執(zhí)行新任務(wù)#include<sys/types.h>#include<stdio.h>#include<unistd.h>intmain(){pid_tpid;/*forkachildprocess*/pid=fork();if(pid<0){/*erroroccurred*/fprintf(stderr,"ForkFailed");return1;}elseif(pid==0){/*子進(jìn)程*/execlp("/bin/ls","ls",NULL);}else{/*父進(jìn)程*//*父進(jìn)程將一直等到,直到子進(jìn)程運(yùn)行完畢*/wait(NULL);printf("ChildComplete");}return0;}//myshell#include<iostream>#include<cstdlib>#include<unistd.h>#include<stdlib.h>#include<stdio.h>#include<string.h>#include<fcntl.h>#include<errno.h>#include<pwd.h>#include<signal.h>#include<sys/wait.h>#include<sys/types.h>#include<sys/stat.h>#include<memory.h>usingnamespacestd;constintmax_hostname_length=256;constintmax_pathname_length=512;charpro_prints[max_hostname_length];voidpro_print(){structpasswd*pwd;charhost_name[max_hostname_length];charpath_name[max_pathname_length];intlength;char*p=getcwd(path_name,40);//char*dir=NULL;//獲取當(dāng)前工作目錄的名字//dir=(char*)get_current_dir_name();//printf("dir:%s\n",dir);char*twd=NULL;twd=getwd(path_name);pwd=getpwuid(getuid());if(gethostname(host_name,sizeof(host_name))==0)sprintf(pro_prints,"[MyShell-tyx]%s@%s%s:",pwd->pw_name,host_name,path_name);elsesprintf(pro_prints,"[MyShell-tyx]%s@unknown%s:",pwd->pw_name,path_name);//cout<<"pleaseinputyourcommand:";cout<<pro_prints;}constintcommand_length=512;charcom[command_length];charpro_argv[command_length];charaft_argv[command_length];voidget_command(){memset(com,0,command_length);intlen=0;intch;ch=getchar();while(len<command_length&&ch!='\n'){com[len++]=ch;ch=getchar();}if(len==command_length){cout<<"commandistoolong!!!"<<endl;exit(0);}}voidanaly_command(){//保留,用來備用后續(xù)添加完善shell}intcommand_in(){//cout<<com<<endl;if(strcmp(com,"exit")==0||strcmp(com,"quit")==0||strcmp(com,"bye")==0){exit(0);}elseif(strcmp(com,"help")==0){cout<<"cd改變當(dāng)前目錄,如果不加參數(shù)則顯示當(dāng)前目錄。"<<endl;cout<<"environ輸出打印當(dāng)前的環(huán)境變量"<<endl;cout<<"echo在shell中打印echo之后的字符串"<<endl;cout<<"help顯示幫助信息"<<endl;cout<<"jobs顯示當(dāng)前進(jìn)程的所有子進(jìn)程"<<endl;cout<<"quit,exit,bye退出當(dāng)前shell"<<endl;cout<<""<<endl;}elseif(strcmp(com,"environ")==0){execlp("env","env",(char*)0);}elseif(strcmp(com,"jobs")==0){execlp("jobs","jobs","-l",(char*)0);}elseif(strcmp(com,"cd")==0){//execlp("/bin/ls","ls",(char*)0);cout<<getcwd(NULL,NULL)<<endl;}else{char*p;char*tmp;p=strtok_r(com,"",&tmp);if(strcmp(p,"echo")==0){//cout<<com<<endl;p=strtok_r(NULL,"",&tmp);cout<<p<<endl;}elseif(strcmp(p,"cd")==0){p=strtok_r(NULL,"",&tmp);chdir(p);//cout<<com<<endl;//cout<<p<<endl;cout<<getcwd(NULL,NULL)<<endl;}}}intmain(intargc,char**argv){while(true){pro_print();get_command();//analy_command();if(command_in()){continue;}}return0;}實(shí)驗(yàn)結(jié)果與分析進(jìn)程的創(chuàng)建步驟3:20次每一次的結(jié)果都是一樣的,原因是因?yàn)樵?.6.32之后的內(nèi)核都是優(yōu)先執(zhí)行父進(jìn)程再執(zhí)行子進(jìn)程,因此每次結(jié)果都是一樣。子進(jìn)程執(zhí)行新任務(wù)步驟3:這個(gè)的分析和上一個(gè)的差不多,因?yàn)樵?.6.32之后的內(nèi)核都是優(yōu)先執(zhí)行父進(jìn)程再執(zhí)行子進(jìn)程,因此父進(jìn)程首先進(jìn)入等待狀態(tài),等待子進(jìn)程執(zhí)行完成之后再做自己的事。實(shí)現(xiàn)一個(gè)簡單的shell(命令行解釋器)(此任務(wù)有一點(diǎn)難度,可選做)。小結(jié)與心得體會(huì)弄清楚父子進(jìn)程的執(zhí)行順序很重要,這個(gè)需要關(guān)注內(nèi)核的調(diào)度函數(shù),因此,多看內(nèi)核函數(shù)總不是一件很吃虧的事,能夠讓我們更好地熟悉和使用一系列Linux函數(shù),并且能夠保持較高的高效性。
實(shí)驗(yàn)三實(shí)驗(yàn)題目實(shí)驗(yàn)三互斥與同步實(shí)驗(yàn)?zāi)康幕仡櫜僮飨到y(tǒng)進(jìn)程、線程的有關(guān)概念,加深對(duì)Windows線程的理解。了解互斥體對(duì)象,利用互斥與同步操作編寫生產(chǎn)者-消費(fèi)者問題的并發(fā)程序,加深對(duì)P(即semWait)、V(即semSignal)原語以及利用P、V原語進(jìn)行進(jìn)程間同步與互斥操作的理解??傮w設(shè)計(jì)生產(chǎn)者消費(fèi)者問題步驟1:創(chuàng)建一個(gè)“Win32ConsolApplication”工程,然后拷貝清單3-1中的程序,編譯成可執(zhí)行文件。步驟2:在“命令提示符”窗口運(yùn)行步驟1中生成的可執(zhí)行文件,列出運(yùn)行結(jié)果。步驟3:仔細(xì)閱讀源程序,找出創(chuàng)建線程的WINDOWSAPI函數(shù),回答下列問題:線程的第一個(gè)執(zhí)行函數(shù)是什么(從哪里開始執(zhí)行)?它位于創(chuàng)建線程的API函數(shù)的第幾個(gè)參數(shù)中?步驟4:修改清單3-1中的程序,調(diào)整生產(chǎn)者線程和消費(fèi)者線程的個(gè)數(shù),使得消費(fèi)者數(shù)目大與生產(chǎn)者,看看結(jié)果有何不同。察看運(yùn)行結(jié)果,從中你可以得出什么結(jié)論?步驟5:修改清單3-1中的程序,按程序注釋中的說明修改信號(hào)量EmptySemaphore的初始化方法,看看結(jié)果有何不同。步驟6:根據(jù)步驟4的結(jié)果,并查看MSDN,回答下列問題:CreateMutex中有幾個(gè)參數(shù),各代表什么含義。CreateSemaphore中有幾個(gè)參數(shù),各代表什么含義,信號(hào)量的初值在第幾個(gè)參數(shù)中。程序中P、V原語所對(duì)應(yīng)的實(shí)際WindowsAPI函數(shù)是什么,寫出這幾條語句。CreateMutex能用CreateSemaphore替代嗎?嘗試修改程序3-1,將信號(hào)量Mutex完全用CreateSemaphore及相關(guān)函數(shù)實(shí)現(xiàn)。寫出要修改的語句。讀者寫者問題(選做)根據(jù)實(shí)驗(yàn)(1)中所熟悉的P、V原語對(duì)應(yīng)的實(shí)際WindowsAPI函數(shù),并參考教材中讀者、寫者問題的算法原理,嘗試?yán)肳indowsAPI函數(shù)實(shí)現(xiàn)第一類讀者寫者問題(讀者優(yōu)先)。詳細(xì)設(shè)計(jì)關(guān)鍵代碼清單3-1生產(chǎn)者消費(fèi)者問題#include<windows.h>#include<iostream>constunsignedshortSIZE_OF_BUFFER=2;//緩沖區(qū)長度unsignedshortProductID=0;//產(chǎn)品號(hào)unsignedshortConsumeID=0;//將被消耗的產(chǎn)品號(hào)unsignedshortin=0;//產(chǎn)品進(jìn)緩沖區(qū)時(shí)的緩沖區(qū)下標(biāo)unsignedshortout=0;//產(chǎn)品出緩沖區(qū)時(shí)的緩沖區(qū)下標(biāo)intbuffer[SIZE_OF_BUFFER];//緩沖區(qū)是個(gè)循環(huán)隊(duì)列boolp_ccontinue=true;//控制程序結(jié)束HANDLEMutex;//用于線程間的互斥HANDLEFullSemaphore;//當(dāng)緩沖區(qū)滿時(shí)迫使生產(chǎn)者等待HANDLEEmptySemaphore;//當(dāng)緩沖區(qū)空時(shí)迫使消費(fèi)者等待DWORDWINAPIProducer(LPVOID);//生產(chǎn)者線程DWORDWINAPIConsumer(LPVOID);//消費(fèi)者線程intmain(){//創(chuàng)建各個(gè)互斥信號(hào)//注意,互斥信號(hào)量和同步信號(hào)量的定義方法不同,互斥信號(hào)量調(diào)用的是CreateMutex函數(shù),同步信號(hào)量調(diào)用的是CreateSemaphore函數(shù),函數(shù)的返回值都是句柄。Mutex=CreateMutex(NULL,FALSE,NULL);EmptySemaphore=CreateSemaphore(NULL,SIZE_OF_BUFFER,SIZE_OF_BUFFER,NULL);//將上句做如下修改,看看結(jié)果會(huì)怎樣//EmptySemaphore=CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL);FullSemaphore=CreateSemaphore(NULL,0,SIZE_OF_BUFFER,NULL);//調(diào)整下面的數(shù)值,可以發(fā)現(xiàn),當(dāng)生產(chǎn)者個(gè)數(shù)多于消費(fèi)者個(gè)數(shù)時(shí),//生產(chǎn)速度快,生產(chǎn)者經(jīng)常等待消費(fèi)者;反之,消費(fèi)者經(jīng)常等待constunsignedshortPRODUCERS_COUNT=3;//生產(chǎn)者的個(gè)數(shù)constunsignedshortCONSUMERS_COUNT=1;//消費(fèi)者的個(gè)數(shù)//總的線程數(shù)constunsignedshortTHREADS_COUNT=PRODUCERS_COUNT+CONSUMERS_COUNT;HANDLEhThreads[THREADS_COUNT];//各線程的handleDWORDproducerID[PRODUCERS_COUNT];//生產(chǎn)者線程的標(biāo)識(shí)符DWORDconsumerID[CONSUMERS_COUNT];//消費(fèi)者線程的標(biāo)識(shí)符//創(chuàng)建生產(chǎn)者線程for(inti=0;i<PRODUCERS_COUNT;++i){hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]);if(hThreads[i]==NULL)return-1;}//創(chuàng)建消費(fèi)者線程for(i=0;i<CONSUMERS_COUNT;++i){hThreads[PRODUCERS_COUNT+i]=CreateThread(NULL,0,Consumer,NULL,0,&consumerID[i]);if(hThreads[i]==NULL)return-1;}while(p_ccontinue){if(getchar()){//按回車后終止程序運(yùn)行p_ccontinue=false;}}return0;}//生產(chǎn)一個(gè)產(chǎn)品。簡單模擬了一下,僅輸出新產(chǎn)品的ID號(hào)voidProduce(){std::cout<<std::endl<<"Producing"<<++ProductID<<"...";std::cout<<"Succeed"<<std::endl;}//把新生產(chǎn)的產(chǎn)品放入緩沖區(qū)voidAppend(){std::cerr<<"Appendingaproduct...";buffer[in]=ProductID;in=(in+1)%SIZE_OF_BUFFER;std::cerr<<"Succeed"<<std::endl;//輸出緩沖區(qū)當(dāng)前的狀態(tài)for(inti=0;i<SIZE_OF_BUFFER;++i){std::cout<<i<<":"<<buffer[i];if(i==in)std::cout<<"<--生產(chǎn)";if(i==out)std::cout<<"<--消費(fèi)";std::cout<<std::endl;}}//從緩沖區(qū)中取出一個(gè)產(chǎn)品voidTake(){std::cerr<<"Takingaproduct...";ConsumeID=buffer[out];buffer[out]=0;out=(out+1)%SIZE_OF_BUFFER;std::cerr<<"Succeed"<<std::endl;//輸出緩沖區(qū)當(dāng)前的狀態(tài)for(inti=0;i<SIZE_OF_BUFFER;++i){std::cout<<i<<":"<<buffer[i];if(i==in)std::cout<<"<--生產(chǎn)";if(i==out)std::cout<<"<--消費(fèi)";std::cout<<std::endl;}}//消耗一個(gè)產(chǎn)品voidConsume(){std::cout<<"Consuming"<<ConsumeID<<"...";std::cout<<"Succeed"<<std::endl;}//生產(chǎn)者DWORDWINAPIProducer(LPVOIDlpPara){while(p_ccontinue){WaitForSingleObject(EmptySemaphore,INFINITE);//p(empty);WaitForSingleObject(Mutex,INFINITE);//p(mutex);Produce();Append();Sleep(1500);ReleaseMutex(Mutex);//V(mutex);ReleaseSemaphore(FullSemaphore,1,NULL);//V(full);}return0;}//消費(fèi)者DWORDWINAPIConsumer(LPVOIDlpPara){while(p_ccontinue){WaitForSingleObject(FullSemaphore,INFINITE);//P(full);WaitForSingleObject(Mutex,INFINITE);//P(mutex);Take();Consume();Sleep(1500);ReleaseMutex(Mutex);//V(mutex);ReleaseSemaphore(EmptySemaphore,1,NULL);//V(empty);}return0;}//讀者與寫者問題讀者先#include"stdafx.h"#include<stdio.h>#include<process.h>#include<windows.h>#include<iostream>usingnamespacestd;unsignedshortcount=0;//讀者的數(shù)量計(jì)數(shù)器//constunsignedshortMax_Count=10;boolIfCountinue=true;//主程序結(jié)束的標(biāo)志HANDLEmutex_count;//讀者數(shù)量的鎖HANDLEmutex_rw;//讀寫鎖DWORDWINAPIWriter(LPVOID);DWORDWINAPIReader(LPVOID);intmain(){mutex_count=CreateMutex(NULL,FALSE,NULL);mutex_rw=CreateMutex(NULL,FALSE,NULL);constunsignedshortreaders=2;//最大的讀者量constunsignedshortwriters=1;//最大的寫者量constunsignedshortall_s=readers+writers;//讀寫者總量HANDLEhandle_all_s[all_s];DWORDreadersID[readers];DWORDwritersID[writers];for(inti=0;i<writers;i++){handle_all_s[i]=CreateThread(NULL,0,Writer,NULL,0,&writersID[i]);//創(chuàng)建寫者線程if(handle_all_s[i]==NULL){return-1;}}for(inti=0;i<readers;i++){handle_all_s[writers+i]=CreateThread(NULL,0,Reader,NULL,0,&readersID[i]);//創(chuàng)建讀者線程if(handle_all_s[writers+i]==NULL){return-1;}}boolget=getchar();//等待輸入字符結(jié)束主進(jìn)程if(get==true){IfCountinue=false;}return0;}voidwriting(){cout<<"Iamawriter!!!"<<endl<<endl;Sleep(1000);}voidreading(){cout<<"Iamareader,thereare(is)"<<::count<<"readershear!"<<endl<<endl;Sleep(1000);}DWORDWINAPIWriter(LPVOIDlpPara){while(IfCountinue){WaitForSingleObject(mutex_rw,INFINITE);//鎖住讀寫鎖,每次一個(gè)人操作writing();ReleaseMutex(mutex_rw);//釋放讀寫鎖}return0;}DWORDWINAPIReader(LPVOIDlpPara){while(IfCountinue){WaitForSingleObject(mutex_count,INFINITE);//開啟讀者數(shù)量鎖,每次只能一個(gè)線程進(jìn)入進(jìn)行操作if(::count==0){WaitForSingleObject(mutex_rw,INFINITE);//鎖住讀寫鎖,每次一個(gè)人操作}::count++;ReleaseMutex(mutex_count);//釋放讀者數(shù)量鎖reading();WaitForSingleObject(mutex_count,INFINITE);//開啟讀者數(shù)量鎖,每次只能一個(gè)線程進(jìn)入進(jìn)行操作::count--;if(::count==0){ReleaseMutex(mutex_rw);//釋放讀寫鎖}ReleaseMutex(mutex_count);//釋放讀者數(shù)量鎖}return0;}實(shí)驗(yàn)結(jié)果與分析生產(chǎn)者消費(fèi)者問題步驟2:步驟3:線程的第一個(gè)執(zhí)行函數(shù)是第三個(gè)參數(shù)指定的函數(shù),位于CreateThread的第三個(gè)參數(shù)。步驟4:消費(fèi)者數(shù)目大于生產(chǎn)者的時(shí)候,消費(fèi)者總是在等待生產(chǎn)者,由此得知數(shù)量多的線程執(zhí)行的次數(shù)也多,成正比關(guān)系。步驟5:修改之后程序沒有反應(yīng),說明沒有可用的信號(hào)量,程序陷入饑餓的狀態(tài)。步驟6:CreateMutex有三個(gè)參數(shù),第一個(gè)是指向安全屬性的指針,第二個(gè)是初始化互斥對(duì)象的所有者,第三個(gè)是指向互斥對(duì)象名的指針。CreateSemaphore有四個(gè)參數(shù),第一個(gè)參數(shù)定義了信號(hào)量的安全特性,第二個(gè)參數(shù)設(shè)置信號(hào)量的初始計(jì)數(shù),第三個(gè)參數(shù)設(shè)置信號(hào)量的最大計(jì)數(shù),第四個(gè)參數(shù)指定信號(hào)量對(duì)象的名稱;信號(hào)量的初值在第二個(gè)參數(shù)中。P()對(duì)應(yīng)的是WaitForSingleObject(),V()對(duì)應(yīng)的是ReleaseMutex()或者ReleaseSemaphore()。CreateMutex能用CreateSemaphore替代,CreateMutex(NULL,FALSE,NULL)改成CreateSemaphore(NULL,0,1,NULL)。讀者寫者問題(選做)小結(jié)與心得體會(huì)編寫程序首先得確定思路,然后再考慮具體的實(shí)現(xiàn),實(shí)現(xiàn)的同時(shí)可以考慮多種方法,比如上面的CreateMutex改成CreateSemaphore,不能掛死在同一棵樹上。
實(shí)驗(yàn)四實(shí)驗(yàn)題目實(shí)驗(yàn)四銀行家算法的模擬與實(shí)現(xiàn)實(shí)驗(yàn)?zāi)康倪M(jìn)一步了解進(jìn)程的并發(fā)執(zhí)行。加強(qiáng)對(duì)進(jìn)程死鎖的理解,理解安全狀態(tài)與不安全狀態(tài)的概念。掌握使用銀行家算法避免死鎖問題??傮w設(shè)計(jì)基本概念死鎖:多個(gè)進(jìn)程在執(zhí)行過程中,因?yàn)楦偁庂Y源會(huì)造成相互等待的局面。如果沒有外力作用,這些進(jìn)程將永遠(yuǎn)無法向前推進(jìn)。此時(shí)稱系統(tǒng)處于死鎖狀態(tài)或者系統(tǒng)產(chǎn)生了死鎖。安全序列:系統(tǒng)按某種順序并發(fā)進(jìn)程,并使它們都能達(dá)到獲得最大資源而順序完成的序列為安全序列。安全狀態(tài):能找到安全序列的狀態(tài)稱為安全狀態(tài),安全狀態(tài)不會(huì)導(dǎo)致死鎖。不安全狀態(tài):在當(dāng)前狀態(tài)下不存在安全序列,則系統(tǒng)處于不安全狀態(tài)。銀行家算法銀行家算法顧名思義是來源于銀行的借貸業(yè)務(wù),一定數(shù)量的本金要滿足多個(gè)客戶的借貸周轉(zhuǎn),為了防止銀行家資金無法周轉(zhuǎn)而倒閉,對(duì)每一筆貸款,必須考察其是否能限期歸還。在操作系統(tǒng)中研究資源分配策略時(shí)也有類似問題,系統(tǒng)中有限的資源要供多個(gè)進(jìn)程使用,必須保證得到的資源的進(jìn)程能在有限的時(shí)間內(nèi)歸還資源,以供其它進(jìn)程使用資源。如果資源分配不當(dāng),就會(huì)發(fā)生進(jìn)程循環(huán)等待資源,則進(jìn)程都無法繼續(xù)執(zhí)行下去的死鎖現(xiàn)象。當(dāng)一進(jìn)程提出資源申請(qǐng)時(shí),銀行家算法執(zhí)行下列步驟以決定是否向其分配資源:檢查該進(jìn)程所需要的資源是否已超過它所宣布的最大值。檢查系統(tǒng)當(dāng)前是否有足夠資源滿足該進(jìn)程的請(qǐng)求。系統(tǒng)試探著將資源分配給該進(jìn)程,得到一個(gè)新狀態(tài)。執(zhí)行安全性算法,若該新狀態(tài)是安全的,則分配完成;若新狀態(tài)是不安全的,則恢復(fù)原狀態(tài),阻塞該進(jìn)程。實(shí)驗(yàn)內(nèi)容本實(shí)驗(yàn)的內(nèi)容是要通過編寫和調(diào)試一個(gè)模擬系統(tǒng)動(dòng)態(tài)分配資源的銀行家算法程序,有效地避免死鎖發(fā)生。具體要求如下:初始化時(shí)讓系統(tǒng)擁有一定的資源;用鍵盤輸入的方式允許進(jìn)程動(dòng)態(tài)申請(qǐng)資源;如果試探分配后系統(tǒng)處于安全狀態(tài),則修改系統(tǒng)的資源分配情況,正式分配資源;如果試探分配后系統(tǒng)處于不安全狀態(tài),則提示不能滿足請(qǐng)求,恢復(fù)原狀態(tài)并阻塞該進(jìn)程。詳細(xì)設(shè)計(jì)主要的數(shù)據(jù)結(jié)構(gòu)程序流程圖關(guān)鍵代碼//初始化voidBanker_Algorithm::Initialization(){qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));//資源總量for(inti=0;i<Num_ResourseAndAvailable;i++){inttempAlloc=0;resLoop:if((tempAlloc=qrand()%20)>=15){Resourse[i]=tempAlloc;//qDebug()<<"Resourse"<<i<<"="<<Resourse[i];Available[i]=tem
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度土地承包經(jīng)營權(quán)續(xù)包與調(diào)整合同模板4篇
- 2025年度商鋪?zhàn)赓U合同環(huán)保與節(jié)能條款規(guī)范4篇
- 2025年伊捷卡項(xiàng)目可行性研究報(bào)告
- 2025年江西宜春公交集團(tuán)有限公司招聘筆試參考題庫含答案解析
- 2025年浙江嘉興興港熱網(wǎng)有限公司招聘筆試參考題庫含答案解析
- 2025年安徽亳州市蒙城縣城投集團(tuán)招聘筆試參考題庫含答案解析
- 2025年浙江余杭旅游集團(tuán)有限公司招聘筆試參考題庫含答案解析
- 2025年浙江國企杭州建德市公共交通運(yùn)輸有限公司招聘筆試參考題庫附帶答案詳解
- 漳州理工職業(yè)學(xué)院《教學(xué)技能培訓(xùn)》2023-2024學(xué)年第一學(xué)期期末試卷
- 張家口職業(yè)技術(shù)學(xué)院《智慧供應(yīng)鏈管理實(shí)訓(xùn)》2023-2024學(xué)年第一學(xué)期期末試卷
- 100個(gè)超高難度繞口令大全
- 《鄭伯克段于鄢》-完整版課件
- (日文文書模板范例)請(qǐng)求書-請(qǐng)求書
- 土壤肥料全套課件
- 畢業(yè)生延期畢業(yè)申請(qǐng)表
- 學(xué)校6S管理制度
- 肽的健康作用及應(yīng)用課件
- T.C--M-ONE效果器使用手冊(cè)
- 8小時(shí)等效A聲級(jí)計(jì)算工具
- 人教版七年級(jí)下冊(cè)數(shù)學(xué)計(jì)算題300道
- 社會(huì)實(shí)踐登記表
評(píng)論
0/150
提交評(píng)論