![操作系統(tǒng)課程設(shè)計實驗報告_第1頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/13/2b2ff6d9-3e3c-4f30-a068-17c77eef5105/2b2ff6d9-3e3c-4f30-a068-17c77eef51051.gif)
![操作系統(tǒng)課程設(shè)計實驗報告_第2頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/13/2b2ff6d9-3e3c-4f30-a068-17c77eef5105/2b2ff6d9-3e3c-4f30-a068-17c77eef51052.gif)
![操作系統(tǒng)課程設(shè)計實驗報告_第3頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/13/2b2ff6d9-3e3c-4f30-a068-17c77eef5105/2b2ff6d9-3e3c-4f30-a068-17c77eef51053.gif)
![操作系統(tǒng)課程設(shè)計實驗報告_第4頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/13/2b2ff6d9-3e3c-4f30-a068-17c77eef5105/2b2ff6d9-3e3c-4f30-a068-17c77eef51054.gif)
![操作系統(tǒng)課程設(shè)計實驗報告_第5頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/13/2b2ff6d9-3e3c-4f30-a068-17c77eef5105/2b2ff6d9-3e3c-4f30-a068-17c77eef51055.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、湖南科技大學(xué)計算機科學(xué)與工程學(xué)院操作系統(tǒng)課程設(shè)計報告學(xué)號:姓名:班級:指導(dǎo)老師:完成時間:2017年6月23日目錄實驗一1、 實驗題目2、 實驗?zāi)康?、 總體設(shè)計四、詳細(xì)設(shè)計五、實驗結(jié)果與分析六、小結(jié)與心得體會實驗二1、 實驗題目2、 實驗?zāi)康?、 總體設(shè)1 四、詳細(xì)設(shè)計五、實驗結(jié)果與分析六、小結(jié)與心得體會實驗三1、 實驗題目2、 實驗?zāi)康?、 總體設(shè)計四、詳細(xì)設(shè)計五、實驗結(jié)果與分析六、小結(jié)與心得體會實驗四1、 實驗題目2、 實驗?zāi)康?、 總體設(shè)計四、詳細(xì)設(shè)計五、實驗結(jié)果與分析六、小結(jié)與心得體會實驗五1、 實驗題目2、 實驗?zāi)康?、 總體設(shè)計四、詳細(xì)設(shè)計五、 實驗結(jié)果與分析.六、小結(jié)與心得體會
2、實驗六實驗題目2、 實驗?zāi)康?、 總體設(shè)計四、詳細(xì)設(shè)計五、實驗結(jié)果與分析六、小結(jié)與心得體會實驗七1、 實驗題目2、 實驗?zāi)康?、 總體設(shè)計四、詳細(xì)設(shè)計五、實驗結(jié)果與分析六、小結(jié)與心得體會實驗八1、 實驗題目_2、 實驗?zāi)康?、 總體設(shè)計四、詳細(xì)設(shè)計五、實驗結(jié)果與分析六、小結(jié)與心得體會.J實驗一一、實驗題目實驗一 Windows進(jìn)程管理二、實驗?zāi)康?)學(xué)會使用 VC編寫基本的 Win32 Consol Application(控制臺應(yīng)用程序)。2)通過創(chuàng)建進(jìn)程、觀察正在運行的進(jìn)程和終止進(jìn)程的程序設(shè)計和調(diào)試操作,進(jìn)一步熟悉操作系統(tǒng)的進(jìn)程概念,理解 Windows進(jìn)程的“一生”。3)通過閱讀和分析實
3、驗程序,學(xué)習(xí)創(chuàng)建進(jìn)程、觀察進(jìn)程、終止進(jìn)程以及父子進(jìn)程同步的基本程序設(shè)計方法0總體設(shè)計1)背景知識Windows所創(chuàng)建的每個進(jìn)程都從調(diào)用CreateProcess()API函數(shù)開始,該函數(shù)的任務(wù)是在對象管理器子系統(tǒng)內(nèi)初始化進(jìn) 程對象。每一進(jìn)程都以調(diào)用 ExitProcess() 或 TerminateProcess() API函數(shù)終止。通常應(yīng)用程序的框架負(fù)責(zé)調(diào)用ExitProcess() 函數(shù)。對于C+運行庫來說,這一調(diào)用發(fā) 生在應(yīng)用程序的main()函數(shù)返回之后。a)創(chuàng)建進(jìn)程CreateProcess()調(diào)用的核心參數(shù)是可執(zhí)行文件運行時的文件名及其命令行。表1-1詳細(xì)地列出了每個參數(shù)的 類型和
4、名稱。可以指定第一個參數(shù),即應(yīng)用程序的名稱,其中包括 相對于當(dāng)前進(jìn)程的當(dāng)前目錄的全路徑或者利用搜索方法找 到的路徑;IpCommandLine參數(shù)允許調(diào)用者向新應(yīng)用程序 發(fā)送數(shù)據(jù);接下來的三個參數(shù)與進(jìn)程和它的主線程以及返 回的指向該對象的句柄的安全性有關(guān)。然后是標(biāo)志參數(shù),用以在dwCreationFlags參數(shù)中指明系統(tǒng)應(yīng)該給予新進(jìn)程什么行為。經(jīng)常使用的標(biāo)志是 CREATE_SUSPNDED訴主線程立刻暫停。當(dāng)準(zhǔn)備好時,應(yīng) 該使用ResumeThread() API 來啟動進(jìn)程。另一個常用的 標(biāo)志是CREATE_NEW_CONSOLE於新進(jìn)程啟動自己的控制 臺窗口,而不是利用父窗口。這一參數(shù)還
5、允許設(shè)置進(jìn)程的優(yōu)先級,用以向系統(tǒng)指明,相對于系統(tǒng)中所有其他的活動進(jìn)程來說,給此進(jìn)程多少 CPU時間。接著是CreateProcess()函數(shù)調(diào)用所需要的三個通常使用缺省值的參數(shù)。第一個參數(shù)是IpEnvironment參數(shù), 指明為新進(jìn)程提供的環(huán)境;第二個參數(shù)是 IpCurrentDirectory ,可用于向主創(chuàng)進(jìn)程發(fā)送與缺省目錄 不同的新進(jìn)程使用的特殊的當(dāng)前目錄;第三個參數(shù)是STARTUPINF段據(jù)結(jié)構(gòu)所必需的,用于在必要時指明新應(yīng) 用程序的主窗口的外觀。CreateProcess() 的最后一個參數(shù)是用于新進(jìn)程對象 及其主線程的句柄和ID的返回值緩沖區(qū)。以 PROCESS_INFORMAT
6、ION 構(gòu) 中返回 的句 柄調(diào)用 CloseHandle() API函數(shù)是重要的,因為如果不將這些句柄關(guān)閉的話,有可能危及主創(chuàng)進(jìn)程終止之前的任何未釋放 的資源。b)正在運行的進(jìn)程如果一個進(jìn)程擁有至少一個執(zhí)行線程,則為正在系統(tǒng)中 運行的進(jìn)程。通常,這種進(jìn)程使用主線程來指示它的存在。當(dāng)主線程結(jié)束時,調(diào)用 ExitProcess() API 函數(shù),通知系 統(tǒng)終止它所擁有的所有正在運行、準(zhǔn)備運行或正在掛起的其 他線程。當(dāng)進(jìn)程正在運行時,可以查看它的許多特性,其中 少數(shù)特性也允許加以修改首先可查看的進(jìn)程特性是系統(tǒng)進(jìn)程標(biāo)識符(PID),可利 用 GetCurrentProcessId() API 函數(shù)來
7、查看,與 GetCurrentProcess() 相似,對該函數(shù)的調(diào)用不能失敗,但 返回的PID在整個系統(tǒng)中都可使用。其他的可顯示當(dāng)前進(jìn) 程信息的 API函數(shù)還有 GetStartupInfo() 和 GetProcessShutdownParameters(),可給出進(jìn)程存活期內(nèi) 的配置詳情。通常,一個進(jìn)程需要它的運行期環(huán)境的信息。例如 API 函數(shù) GetModuleFileName() 和 GetCommandLine(),可以給 出用在CreateProcess()中的參數(shù)以啟動應(yīng)用程序。在創(chuàng)建應(yīng)用程序時可使用的另一個 API函數(shù)是 IsDebuggerPresent() ??衫肁P
8、I函數(shù)GetGuiResources()來查看進(jìn)程的GUI資源。此函數(shù)既可返回指定進(jìn)程中的打開的GUI對象的數(shù)目,也可返回指定進(jìn)程中打開的USER對象的數(shù)目。進(jìn)程 的其他性能信 息可通過 GetProcessIoCounters()、 GetProcessPriorityBoost() 、 GetProcessTimes() 和 GetProcessWorkingSetSize()API 得到。以上這幾個API函數(shù)者B只需要具有 PROCESS_QUERY_INFORMATION權(quán)限 的指向所感興趣進(jìn)程的句柄。另一個可用于進(jìn)程信息查詢的 API函數(shù)是GetProcessVersion() 。此
9、函數(shù)只需感興趣進(jìn)程的 PID(進(jìn)程標(biāo)識號)。這一 API函數(shù)與GetVersionEx()的共同作用,可確定運行進(jìn)程的系統(tǒng)的版本號。c)終止進(jìn)程所有進(jìn)程都是以調(diào)用 ExitProcess() 或者 TerminateProcess()函數(shù)結(jié)束的。但最好使用前者而不要使用后者,因為進(jìn)程是在完成了它的所有的關(guān)閉“職責(zé)”之 后以正常的終止方式來調(diào)用前者的。而外部進(jìn)程通常調(diào)用后 者即突然終止進(jìn)程的進(jìn)行,由于關(guān)閉時的途徑不太正常,有 可能引起錯誤的行為。TerminateProcess() API函數(shù)只要打開帶有PROCESS_TERMINATE、可權(quán)的進(jìn)程對象,就可以終止進(jìn)程, 并向系統(tǒng)返回指定的代碼
10、。這是一種“野蠻”的終止進(jìn)程的 方式,但是有時卻是需要的。如果開發(fā)人員確實有機會來設(shè)計“謀殺”(終止別的進(jìn)程的進(jìn)程)和“受害”進(jìn)程(被終止的進(jìn)程)時,應(yīng)該創(chuàng)建 個進(jìn)程間通訊的內(nèi)核對象一一如一個互斥程序一一這樣 一來,“受害”進(jìn)程只在等待或周期性地測試它是否應(yīng)該終 止。d)進(jìn)程同步Windows提供的常用對象可分成三類:核心應(yīng)用服務(wù)、 線程同步和線程間通訊。 其中,開發(fā)人員可以使用線程同步 對象來協(xié)調(diào)線程和進(jìn)程的工作,以使其共享信息并執(zhí)行任務(wù)。此類對象包括互鎖數(shù)據(jù)、臨界段、事件、互斥體和信號等。多線程編程中關(guān)鍵的一步是保護(hù)所有的共享資源,工具主要有互鎖函數(shù)、臨界段和互斥體等;另一個實質(zhì)性部分是
11、協(xié)調(diào)線程使其完成應(yīng)用程序的任務(wù),為此,可利用內(nèi)核中的事件對象和信號。在進(jìn)程內(nèi)或進(jìn)程間實現(xiàn)線程同步的最方便的方法是使 用事件對象,這一組內(nèi)核對象允許一個線程對其受信狀態(tài)進(jìn) 行直接控制。而互斥體則是另一個可命名且安全的內(nèi)核對象,其主要目的是引導(dǎo)對共享資源的訪問。擁有單一訪問資源的線程創(chuàng) 建互斥體,所有想要訪問該資源的線程應(yīng)該在實際執(zhí)行操作 之前獲得互斥體,而在訪問結(jié)束時立即釋放互斥體,以允許下一個等待線程獲得互斥體,然后接著進(jìn)行下去。與事件對象類似,互斥體容易創(chuàng)建、打開、使用并清除。 利用CreateMutex() API可創(chuàng)建互斥體,創(chuàng)建時還可以指定一個初始的擁有權(quán)標(biāo)志, 通過使用這個標(biāo)志,只有
12、當(dāng)線程 完成了資源的所有的初始化工作時, 才允許創(chuàng)建線程釋放互 斥體。為了獲得互斥體,首先,想要訪問調(diào)用的線程可使用 OpenMutex() API來獲得指向?qū)ο蟮木浔?然后,線程將這 個句柄提供給一個等待函數(shù)。當(dāng)內(nèi)核將互斥體對象發(fā)送給等待線程時,就表明該線程獲得了互斥體的擁有權(quán)。當(dāng)線程獲得擁有權(quán)時,線程控制了對共享資源的訪問一一必須設(shè)法盡 快地放棄互斥體。放棄共享資源時需要在該對象上調(diào)用ReleaseMute() API 。然后系統(tǒng)負(fù)責(zé)將互斥體擁有權(quán)傳遞給 下一個等待著的線程(由到達(dá)時間決定順序)。2)編寫基本的 Win32 Consol Application步驟1 :登錄進(jìn)入 Wind
13、ows系統(tǒng),啟動VC+ 6.0 。步驟2 :在“FILE”菜單中單擊“NEW子菜單,在“projects ”選項卡中選擇 “Win32 ConsolApplication ”,然后在 “Project name處輸入工程名,在“ Location ”處輸入工程目錄。創(chuàng)建一個新的控制臺應(yīng)用程序工程。步驟3 :在“FILE”菜單中單擊“ NEW子菜單,在“ Files ”選 項卡中選擇“ C+ Source File ”,然后在“ File ” 處輸入C/C+ 源程序的文件名。步驟4 :將清單1-1所示的程序清單復(fù)制到新創(chuàng)建的C/C+源程序中。編譯成可執(zhí)行文件。步驟5 :在“開始”菜單中單擊“程序
14、”-“附件”-“命令提示符”命令,進(jìn)入 Windows ”命令提示符窗口,然后進(jìn)入工程目錄 中的debug子目錄,執(zhí)行編譯好的可執(zhí)行程序,列出運行結(jié)果(如果運行不成功,則可能的原因是什么?)3)創(chuàng)建進(jìn)程本實驗顯示了創(chuàng)建子進(jìn)程的基本框架。該程序只是再一次地啟動自身,顯示它的系統(tǒng)進(jìn)程ID和它在進(jìn)程列表中的位置步驟 1 :創(chuàng)建一個 “ Win32 Consol Application ” 工程,然后拷貝清單1-2中的程序,編譯成可執(zhí)行文件。步驟2 :在“命令提示符窗口運行步驟 1中生成的可執(zhí)行文件,列出運行結(jié)果。按下 ctrl+alt+del ,調(diào)用windows的任務(wù)管 理器,記錄進(jìn)程相關(guān)的行為屬
15、性。步驟3 :在“命令提示符窗口加入?yún)?shù)重新運行生成的可執(zhí)行文件,列出運行結(jié)果。按下 ctrl+alt+del ,調(diào)用windows的任 務(wù)管理器,記錄進(jìn)程相關(guān)的行為屬性。步驟4 :修改清單1-2中的程序,將nClone的定義和初始化方法按程序注釋中的修改方法進(jìn)行修改, 編譯成可執(zhí)行文件(執(zhí) 行前請先保存已經(jīng)完成的工作)。再按步驟2中的方式運行,看看 結(jié)果會有什么不一樣。列出行結(jié)果。從中你可以得出什么結(jié)論?說明nClone的作用。變量的定義和初始化方法(位置)對程序的執(zhí)行結(jié)果有影響嗎?為什么?4)父子進(jìn)程的簡單通信及終止進(jìn)程步驟 1 :創(chuàng)建一個 “ Win32 Consol Applicati
16、on ” 工程,然后拷貝清單1-3中的程序,編譯成可執(zhí)行文件。步驟2 :在VC的工具欄單擊“Execute Program(執(zhí)行程序)按鈕,或者按Ctrl + F5鍵,或者在“命令提示符窗口運行步驟1中生成的可執(zhí)行文件,列出運行結(jié)果。步驟3 :按源程序中注釋中的提示,修改源程序1-3 ,編譯執(zhí)行(執(zhí)行前請先保存已經(jīng)完成的工作),列出運行結(jié)果。在程序中加入跟蹤語句,或調(diào)試運行程序,同時參考MSDN中的幫助文件CreateProcess()的使用方法,理解父子進(jìn)程如何傳遞參數(shù)。給出程 序執(zhí)行過程的大概描述。步驟4 :按源程序中注釋中的提示,修改源程序1-3 ,編譯執(zhí)行,列出運行結(jié)果。步驟5 : 參
17、考MSDN中的幫 助文件CreateMutex()、 OpenMutex()、ReleaseMutex()和 WaitForSingleObject() 的使 用方法,理解父子進(jìn)程如何利用互斥體進(jìn)行同步的。給出父子進(jìn)程同步過程的一個大概描述。四、詳細(xì)設(shè)計1)關(guān)鍵代碼清單1-1 一個簡單的 Windows控制臺應(yīng)用程序/ hello 項目#include stdafx.h# include void main()std:cout Hello, Win32 Consol Application std:endl;清單1-2創(chuàng)建子進(jìn)程#define _CRT_SECURE_NO_WARNINGS#i
18、nclude stdafx.h#include #include #include /創(chuàng)建傳遞過來的進(jìn)程的克隆過程并賦于其ID值void StartClone(int nCloneID)/提取用于當(dāng)前可執(zhí)行文件的文件名TCHAR szFilenameMAX_PATH;GetModuleFileName(NULL, szFilename, MAX_PATH);/格式化用于子進(jìn)程的命令行并通知其EXE文件名和克隆IDTCHAR szCmdLineMAX_PATH;sprintf_s(szCmdLine, V%s %d, szFilename, nClonelD);/ 用于子進(jìn)程的 STARTUPI
19、NFO吉構(gòu)STARTUPINFO si;ZeroMemory(&si, sizeof(si);si.cb = sizeof(si); 必須是本結(jié)構(gòu)的大小/返回的用于子進(jìn)程的進(jìn)程信息PROCESS_INFORMATION pi;/利用同樣的可執(zhí)行文件和命令行創(chuàng)建進(jìn)程,并賦于其子進(jìn)程的性質(zhì)BOOL bCreateOK = :CreateProcess(szFilename, 產(chǎn)生這個EXE的應(yīng)用程序的名稱szCmdLine, /告訴其行為像一個子進(jìn)程的標(biāo)志NULL, /缺省的進(jìn)程安全性NULL, /缺省的線程安全性FALSE, /不繼承句柄CREATE_NEW_CONSOLE, NULL, 新的環(huán)
20、境NULL, /當(dāng)前目錄&si, 啟動信息&pi); 返回的進(jìn)程信息/對子進(jìn)程釋放引用if (bCreateOK)CloseHandle(pi.hProcess);CloseHandle(pi.hThread);int main(int argc, char* argv)/確定派生出幾個進(jìn)程,及派生進(jìn)程在進(jìn)程列表中的位置int nClone = 0;/ 修改語句:int nClone;/第一次修改:nClone=0;if (argc 1)/從第二個參數(shù)中提取克隆ID二sscanf_s(argv1, %d, &nClone);使用新的控制臺/第二次修改:nClone=0;/顯示進(jìn)程位置std:c
21、out Process ID: 二GetCurrentProcessId() , Clone ID: nClone std:endl;/檢查是否有創(chuàng)建子進(jìn)程的需要const int c_nCloneMax = 5;if (nClone c_nCloneMax)/發(fā)送新進(jìn)程的命令行和克隆號StartClone(+nClone);/等待響應(yīng)鍵盤輸入結(jié)束進(jìn)程getchar();return 0;清單1-3父子進(jìn)程的簡單通信及終止進(jìn)程的示例程序#include stdafx.h# include # include # include /創(chuàng)建當(dāng)前進(jìn)程的克隆進(jìn)程的簡單方法void StartClone(
22、)TCHAR szFilenameMAX_PATH;GetModuleFileName(NULL, szFilename, MAX_PATH);/格式化用于子進(jìn)程的命令行,字符串“ child ”將作為形參傳遞給子進(jìn)程的main函數(shù)TCHAR szCmdLineMAX_PATH;/ 實驗1-3步驟3:將下句中的字符串child改為別的字符串,重新編譯執(zhí)行,執(zhí)行前請先保存已經(jīng)完成的工作sprintf_s(szCmdLine, %s child, szFilename);/子進(jìn)程的啟動信息結(jié)構(gòu)STARTUPINFO si;ZeroMemory(&si, sizeof(si);si.cb = siz
23、eof(si); 應(yīng)當(dāng)是此結(jié)構(gòu)的大小/返回的用于子進(jìn)程的進(jìn)程信息PROCESS_INFORMATION pi;/用同樣的可執(zhí)行文件名和命令行創(chuàng)建進(jìn)程,并指明它是一個子進(jìn)程BOOL bCreateOK = CreateProcess(szFilename, /產(chǎn)生的應(yīng)用程序的名稱 (本EXE文件)szCmdLine, /告訴我們這是一個子進(jìn)程的標(biāo)志NULL, /用于進(jìn)程的缺省的安全性NULL, /用于線程的缺省安全性不繼承句柄創(chuàng)建新窗口FALSE, /CREATE_NEW_CONSOLE, NULL, 新環(huán)境NULL, /當(dāng)前目錄&si, 啟動信息結(jié)構(gòu)&pi); 返回的進(jìn)程信息/釋放指向子進(jìn)程的
24、引用if (bCreateOK)CloseHandle(pi.hProcess);CloseHandle(pi.hThread);void Parent()/ 創(chuàng)建“自殺”互斥程序體HANDLE hMutexSuicide = CreateMutex(NULL, /缺省的安全性TRUE, 最初擁有的g_szMutexName); /互斥體名稱if (hMutexSuicide != NULL)/創(chuàng)建子進(jìn)程std:cout Creating the child process. std:endl;StartClone();/指令子進(jìn)程“殺”掉自身std:cout Telling the chil
25、d process to quit. std:endl;/等待父進(jìn)程的鍵盤響應(yīng)getchar();/釋放互斥體的所有權(quán),這個信號會發(fā)送給子進(jìn)程的WaitForSingleObject 過程ReleaseMutex(hMutexSuicide);/std:cout 222 std:endl;/ 消除句柄CloseHandle(hMutexSuicide);void Child()/ 打開“自殺”互斥體HANDLE hMutexSuicide = OpenMutex(SYNCHRONIZE, 打開用于同步FALSE, /不需要向下傳遞g_szMutexName); /名稱/std:cout 111
26、 std:endl;if (hMutexSuicide != NULL)/報告我們正在等待指令std:cout Child waiting for suicide instructions.std:endl;/子進(jìn)程進(jìn)入阻塞狀態(tài),等待父進(jìn)程通過互斥體發(fā)來的信號WaitForSingleObject(hMutexSuicide, INFINITE);WaitForSingleObject(hMutexSuicide, 0);/ 實驗1-3步驟4 :將上句改為WaitForSingleObject(hMutexSuicide, 0),重新編譯執(zhí)行/準(zhǔn)備好終止,清除句柄std:cout Child
27、quiting. 1 & 二strcmp(argv1, child) = 0)Sleep(1000);Child();elseSleep(1000);Parent。;return 0;五、實驗結(jié)果與分析1)編寫基本的 Win32 Consol Applicationa)步驟5:運行不成功可能的原因有:雙引號是全角符號,需改成半角符號。2)創(chuàng)建進(jìn)程a)步驟2:b)步驟3:c)步驟4:nClone初始化的地方不同,程序執(zhí)行的次數(shù)也不同,在判斷有無命令行參數(shù)之前初始化的話程序只執(zhí)行規(guī)定的最多的次數(shù);之后初始化的話就會無限創(chuàng)建新進(jìn)程。由此得出變量的定義和初始化方法(位置)對程序的執(zhí)行結(jié)果有影響,因為中
28、間多了一個判斷命令行參數(shù)的代碼段,這一段代碼會更改nClone的值。3)父子進(jìn)程的簡單通信及終止進(jìn)程a)步驟2:b)步驟3:程序判斷有無命令行參數(shù)以及參數(shù)是不是child 是的話就開啟子進(jìn)程,否則就開啟父進(jìn)程。父進(jìn)程在執(zhí)行克隆的時候給自身加上一把鎖從而保證自身是線程安全的函數(shù),同時在 CreateProcess 的第二個參數(shù) 傳入child 參數(shù),保證下次執(zhí)行的是子進(jìn)程,如此循環(huán),使 得父子進(jìn)程能夠并發(fā)進(jìn)行,實現(xiàn)父子進(jìn)程的通信。c)步驟4:d)步驟5:CreateMutex作用是找出當(dāng)前系統(tǒng)是否已經(jīng)存在指定進(jìn)程的實例,如果沒有則創(chuàng)建一個互斥體;OpenMutex函數(shù)為現(xiàn)有的一個已命名互斥體對象
29、創(chuàng)建一個新句柄;ReleaseMutex是一種線性指令,具有釋放線程擁有的互斥體的控制權(quán); WaitForSingleObject 函數(shù)用來檢測hHandle事件的信號狀態(tài)。由父進(jìn)程創(chuàng)建一把鎖后,子進(jìn)程不用創(chuàng)建鎖,用的時候只需要打開就行,保證同一個時間段只能有父進(jìn)程或者子進(jìn)程在 運行。六、小結(jié)與心得體會變量的定義和初始化的位置很重要,因此在進(jìn)行程序設(shè)計的時候需要設(shè)置好變量的位置,否則會出現(xiàn)意想不到的問題。實驗二一、實驗題目實驗二Linux進(jìn)程管理二、實驗?zāi)康耐ㄟ^進(jìn)程的創(chuàng)建、撤銷和運行加深對進(jìn)程概念和進(jìn)程并發(fā)執(zhí)行的理解,明確進(jìn)程和程序之間的區(qū)別。三、總體設(shè)計1)進(jìn)程的創(chuàng)建任務(wù)要求:編寫一段程序,
30、使用系統(tǒng)調(diào)用fork ()創(chuàng)建兩個子進(jìn)程。當(dāng)此程序運行時,在系統(tǒng)中有一個父進(jìn)程和兩個子進(jìn)程活動。讓每一個進(jìn)程在屏幕上顯示一個字符:父進(jìn)程顯示字符“a”;兩子進(jìn)程分別顯示字符“ b”和字符“ c”。試觀察記錄20次運行 該程序在屏幕上的顯示結(jié)果,并分析原因。步驟1 :使用vi或gedit 新建一個forkdemo.c 程序,然 后拷貝清單2-1中的程序,使用cc或者gcc編譯成可執(zhí)行文件 forkdemo。例如,可以使用 gcc - o forkdemo forkdemo.c 完成 編譯。步驟2 :在命令行輸入./fork_demo 運行該程序。步驟3 :觀察記錄20次運行該程序在屏幕上的顯示結(jié)
31、果, 并分析。2)子進(jìn)程執(zhí)行新任務(wù)任務(wù)要求:編寫一段程序,使用系統(tǒng)調(diào)用fork ()創(chuàng)建一個子進(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)識符,然后正常結(jié)束。步驟1 :使用 vi 或 gedit 新建一個 exec_demo.c 程序, 然后拷貝清單2-2中的程序(該程序的執(zhí)行如圖2-1所示),使用cc或者gcc編譯成可執(zhí)行文件exec_demo。例如,可以使用 gcc - oexec_demo exec
32、_demo.c 完成編譯。步驟2 :在命令行輸入./exec_demo運行該程序。步驟3 :觀察該程序在屏幕上的顯示結(jié)果,并分析。3)實現(xiàn)一個簡單的shell(命令行解釋器)(此任務(wù)有一點難度,可選做)。你的shell 類似于sh,bash,csh等,必須支持以下內(nèi)部命令:cd 目錄 更改當(dāng)前的工作目錄到另一個 目錄。如果 目錄, 未指定,輸出當(dāng)前工作目錄。如果 目錄 不存在,應(yīng)當(dāng)有適當(dāng)?shù)腻e 誤信息提示。這個命令應(yīng)該也能改變PWD的環(huán)境變量。environ列出所有環(huán)境變量字符串的設(shè)置 (類似于Unix系統(tǒng)下的env命令)。一一echo 內(nèi)容 顯示echo后的內(nèi)容且換行help簡短概要的輸出你的
33、shell的使用方法和基本功能。jobs輸出shell當(dāng)前的一系列子進(jìn)程,必須提供子進(jìn)程的命 名和PID號。quit,exit,bye 退出 shell 。提示:shell的主體就是反復(fù)下面的循環(huán)過程while(1)接收用戶輸入的命令行;解析命令行;if(用戶命令為內(nèi)部命令)直接處理;else if( 用戶命令為外部命令)創(chuàng)建子進(jìn)程執(zhí)行命令;參考清單2-2else提示錯誤的命令;四、詳細(xì)設(shè)計1)關(guān)鍵代碼清單2-1創(chuàng)建進(jìn)程int main ()int x;while(x=fork()=-1);if (x=0)printf(a);elseprintf(b);printf(c);清單2-2子進(jìn)程執(zhí)行
34、新任務(wù)#include #include #include int main()pid_t pid;/* fork a child process */pid = fork();if (pid 0) /* error occurred */fprintf(stderr, Fork Failed);return 1;else if (pid = 0) /* 子進(jìn)程*/execlp(/bin/ls,ls,NULL);else /* 父進(jìn)程*/*父進(jìn)程將一直等到,直到子進(jìn)程運行完畢*/wait(NULL);printf(Child Complete);return 0;/myshell#includ
35、e #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;const int max_hostname_length = 256;const int max_pathname_length = 512;char pro_printsmax_hostname_length;void pro_print() struct passwd *pwd;char host_namemax_
36、hostname_length;char path_namemax_pathname_length;int length;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)
37、=0)sprintf(pro_prints,MyShell-tyx %s% s:pwd-pw_name, host_name,path_name);elsesprintf(pro_prints, MyShell-tyx %sunknown %s : , pwd-pw_name,path_name);/ cout please input your command:;cout pro_prints;const int command_length = 512;char comcommand_length;char pro_argvcommand_length;char aft_argvcomma
38、nd_length;void get_command() memset(com, 0, command_length);int len = 0;int ch;ch = getchar();while (len command_length & ch != n) comlen+ = ch;ch = getchar();if (len = command_length) cout command is too long! endl;exit(0);void analy_command() / 保留,用來備用后續(xù)添加完善 shellint command_in() / cout com endl;i
39、f (strcmp(com, exit) = 0 | strcmp(com, quit)=0 | strcmp(com, bye) = 0) exit(0); else if (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 end
40、l; else if (strcmp(com, environ) = 0) execlp(env, env, (char*) 0); else if (strcmp(com, jobs) = 0) execlp(jobs, jobs, -l, (char*) 0);else if(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) /co
41、ut com endl;p = strtok_r(NULL, , &tmp);cout p endl; else if (strcmp(p, cd) = 0) p = strtok_r(NULL, , &tmp);chdir(p);/ cout com endl;/ cout p endl;cout getcwd(NULL,NULL) endl;int main(int argc, char* argv) while (true) pro_print();get_command();analy_command();if (command_in() Icontinue;return 0;五、實驗
42、結(jié)果與分析1)進(jìn)程的創(chuàng)建a)步驟3:2)子進(jìn)程執(zhí)行新任務(wù)a)步驟3:3)實現(xiàn)一個簡單的shell (命令行解釋器)(此任務(wù)有一點難度, 可選做)。六、小結(jié)與心得體會弄清楚父子進(jìn)程的執(zhí)行順序很重要,這個需要關(guān)注內(nèi)核的調(diào)度 函數(shù),因此,多看內(nèi)核函數(shù)總不是一件很吃虧的事,能夠讓我們更 好地熟悉和使用一系列 Linux函數(shù),并且能夠保持較高的高效性。實驗三一、實驗題目實驗三互斥與同步二、實驗?zāi)康?)回顧操作系統(tǒng)進(jìn)程、線程的有關(guān)概念,加深對 Windows線程的 理解。2) 了解互斥體對象,利用互斥與同步操作編寫生產(chǎn)者-消費者問題的并發(fā)程序,加深對 P (即semWait)、V(即semSignal)原
43、語以 及利用P、V原語進(jìn)行進(jìn)程間同步與互斥操作的理解。三、總體設(shè)計1)生產(chǎn)者消費者問題步驟 1 :創(chuàng)建一個 “ Win32 Consol Application ” 工程,然后 拷貝清單3-1中的程序,編譯成可執(zhí)行文件。步驟2 :在“命令提示符窗口運行步驟1中生成的可執(zhí)行文件,列出運行結(jié)果。步驟3 :仔細(xì)閱讀源程序,找出創(chuàng)建線程的WINDOWS API函數(shù),回答下列問題:線程的第一個執(zhí)行函數(shù)是什么 (從哪里開始執(zhí) 行)?它位于創(chuàng)建線程的 API函數(shù)的第幾個參數(shù)中?步驟4 :修改清單3-1中的程序,調(diào)整生產(chǎn)者線程和消費者 線程的個數(shù),使得消費者數(shù)目大與生產(chǎn)者,看看結(jié)果有何不同。察看運行結(jié)果,從中
44、你可以得出什么結(jié)論?步驟5 :修改清單3-1中的程序,按程序注釋中的說明修改 信號量EmptySemaphore的初始化方法,看看結(jié)果有何不同。步驟6 :根據(jù)步驟4的結(jié)果,并查看MSDN回答下列問題:a) CreateMutex中有幾個參數(shù),各代表什么含義。b) CreateSemaphore中有幾個參數(shù),各代表什么含義,信號量的初值在第幾個參數(shù)中。c) 程序中P、V原語所對應(yīng)的實際 Windows API函數(shù) 是什么,寫出這幾條語句。d) CreateMutex 能用 CreateSemaphore 替代嗎?嘗 試修改程序 3-1 ,將信號量 Mutex 完全用 CreateSemaphor
45、e 及相關(guān)函數(shù)實現(xiàn)。寫出要修改的語句。2 2)讀者寫者問題(選做)根據(jù)實驗(1)中所熟悉的P、V原語對應(yīng)的實際 Windows API 函數(shù),并參考教材中讀者、寫者問題的算法原理,嘗試?yán)?Windows API函數(shù)實現(xiàn)第一類讀者寫者問題(讀者優(yōu)先)。四、詳細(xì)設(shè)計1)關(guān)鍵代碼清單3-1生產(chǎn)者消費者問題#include #include const unsigned short SIZE_OF_BUFFER = 2; 緩沖區(qū)長度unsigned short ProductID = 0; /產(chǎn)品號unsigned short ConsumeID = 0; /將被消耗的產(chǎn)品號unsigned sho
46、rt in = 0; /產(chǎn)品進(jìn)緩沖區(qū)時的緩沖區(qū)下標(biāo)unsigned short out = 0; /產(chǎn)品出緩沖區(qū)時的緩沖區(qū)下標(biāo)int bufferSIZE_OF_BUFFER; /緩沖區(qū)是個循環(huán)隊列bool p_ccontinue = true; /控制程序結(jié)束HANDLE Mutex; 用于線程間的互斥HANDLE FullSemaphore; /當(dāng)緩沖區(qū)滿時迫使生產(chǎn)者等待HANDLE EmptySemaphore; /當(dāng)緩沖區(qū)空時迫使消費者等待DWORD WINAPI Producer(LPVOID); / 生產(chǎn)者線程DWORD WINAPI Consumer(LPVOID); 消費者線程
47、 int main()/創(chuàng)建各個互斥信號/ 注意,互斥信號量和同步信號量的定義方法不同,互斥信號量調(diào)用 的是CreateMutex 函數(shù),同步信號量調(diào)用的是 CreateSemaphore函數(shù),函數(shù)的返回值都是句 柄。Mutex = CreateMutex(NULL,FALSE,NULL);EmptySemaphore =CreateSemaphore(NULL,SIZE_OF_BUFFER,SIZE_OF_BUFFER,NULL);/將上句做如下修改,看看結(jié)果會怎樣EmptySemaphore =CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL);Fu
48、llSemaphore = CreateSemaphore(NULL,0,SIZE_OF_BUFFER,NULL);/調(diào)整下面的數(shù)值,可以發(fā)現(xiàn),當(dāng)生產(chǎn)者個數(shù)多于消費者個數(shù)時,/生產(chǎn)速度快,生產(chǎn)者經(jīng)常等待消費者;反之,消費者經(jīng)常等待const unsigned short PRODUCERS_COUNT = 3; 生產(chǎn)者的個數(shù) const unsigned short CONSUMERS_COUNT = 1; / 消費者的個數(shù)/ 總的線程數(shù)const unsigned short THREADS_COUNT =PRODUCERS_COUNT+CONSUMERS_COUNT;HANDLE hThr
49、eadsTHREADS_COUNT; 各線程的 handleDWORD producerIDPRODUCERS_COUNT; 生產(chǎn)者線程的標(biāo)識符 DWORD consumerIDCONSUMERS_COUNT;艄費者線程的標(biāo)識符/創(chuàng)建生產(chǎn)者線程for (int i=0;iPRODUCERS_COUNT;+i)hThreadsi=CreateThread(NULL,0,Producer,NULL,0,&producerIDi) ;if (hThreadsi=NULL) return -1;/ 創(chuàng)建消費者線程for (i=0;iCONSUMERS_COUNT;+i)hThreadsPRODUCER
50、S_COUNT+i=CreateThread(NULL,0,Consumer,NULL,0 ,&consumerIDi);if (hThreadsi=NULL) return -1;while(p_ccontinue)if(getchar() /按回車后終止程序運行p_ccontinue = false;return 0;/生產(chǎn)一個產(chǎn)品。簡單模擬了一下,僅輸出新產(chǎn)品的ID號void Produce()std:cout std:endl Producing +ProductID .;std:cout Succeed std:endl;/把新生產(chǎn)的產(chǎn)品放入緩沖區(qū)void Append()std:cerr Appending a product .;bufferin = ProductID;in = (in+1)%SIZE_OF_BUFFER;std:cerr Succeed std:endl;/輸出緩沖區(qū)當(dāng)前的狀態(tài)for (int i=0;iSIZE_OF_BUFFER;+i)std:cout i : bufferi;if (i=in) std:cout -生產(chǎn);if (i=out) std:cout -消費std:cout std:endl;/從緩沖區(qū)中取出一個產(chǎn)品void Take()std:cerr Takin
溫馨提示
- 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)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年B116型一氧化碳中溫變換催化劑合作協(xié)議書
- 2025年大功率電源及系統(tǒng)合作協(xié)議書
- 2025年微電子組件合作協(xié)議書
- 北京和協(xié)航電科技有限公司的射頻研發(fā)筆試題
- 2025年中班幼兒園教師年度個人工作總結(jié)(四篇)
- 2025年節(jié)能高效果汁濃縮設(shè)備合作協(xié)議書
- 2025年鄉(xiāng)村企業(yè)職工勞動合同(五篇)
- 2025年產(chǎn)品租賃協(xié)議樣本(2篇)
- 2025年九年級上冊數(shù)學(xué)教學(xué)工作總結(jié)模版(三篇)
- 2025年二人合伙開店協(xié)議標(biāo)準(zhǔn)版本(三篇)
- GB/T 16818-2008中、短程光電測距規(guī)范
- 控制系統(tǒng)狀態(tài)空間表達(dá)式的解
- (七圣)七圣娘娘簽詩
- 自我同情量表
- 內(nèi)鏡下粘膜剝離術(shù)(ESD)護(hù)理要點及健康教育
- 新媒體文案創(chuàng)作與傳播精品課件(完整版)
- 2022年全省百萬城鄉(xiāng)建設(shè)職工職業(yè)技能競賽暨“華衍杯”江蘇省第三屆供水安全知識競賽題庫
- 廣西北海LNG儲罐保冷施工方案
- 產(chǎn)業(yè)園工程施工組織設(shè)計(技術(shù)標(biāo)近200頁)
- 《生態(tài)學(xué)》課件—第1章:緒論
- 中心靜脈壓(CVP)監(jiān)測及波形分析
評論
0/150
提交評論