日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

操作系统课设之Windows 进程管理

發布時間:2025/3/15 windows 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 操作系统课设之Windows 进程管理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

課程設計開始了,實驗很有意思,寫博客總結學到的知識
白嫖容易,創作不易,學到東西才是真
本文原創,創作不易,轉載請注明!!!
本文鏈接
個人博客:https://ronglin.fun/archives/171
PDF鏈接:見博客網站
CSDN: https://blog.csdn.net/RongLin02/article/details/118308142

為了美觀,實驗源代碼在結尾處,整合版見下
鏈接:https://pan.baidu.com/s/1rXj1QJGuw-BVc5sQWret9w
提取碼:Lin2
操作系統課程設計源代碼
本次操作系統課程設計合集
操作系統課設之Windows 進程管理
操作系統課設之Linux 進程管理
操作系統課設之Linux 進程間通信
操作系統課設之Windows 的互斥與同步
操作系統課設之內存管理
操作系統課設之虛擬內存頁面置換算法的模擬與實現
操作系統課設之基于信號量機制的并發程序設計
操作系統課設之簡單 shell 命令行解釋器的設計與實現
僅用于學習,如有侵權,請聯系我刪除

實驗題目

Windows 進程管理

實驗目的

(1)學會使用 VC 編寫基本的 Win32 Consol Application(控制臺應用程序)。
(2)通過創建進程、觀察正在運行的進程和終止進程的程序設計和調試操作,進一步熟悉操
作系統的進程概念,理解 Windows 進程的“一生”。
(3)通過閱讀和分析實驗程序,學習創建進程、觀察進程、終止進程以及父子進程同步的基本程序設計方法。

實驗內容

由于個人習慣,對于C/C++代碼,我更喜歡用CodeBlocks開發,所以本次驗證性實驗和設計類均用CodeBlocks完成。

1-1 編寫基本的 Win32 Consol Application

這個實驗的主要目的是熟悉編寫C/C++控制臺程序,對于創建一個C/C++控制臺程序,我常用的有兩種方式,逐一說明其優缺點。
第一種方式是在菜單欄點擊 File – New – File… ,在彈出的窗口中選擇 C/C++ source ,然后選擇代碼類型是C還是C++,之后設置文件保存的位置,然后就會生成一個.c(.cpp)文件,在這個文件中就可以編寫c(c++)代碼了。編寫完成后在菜單欄 點擊 Build – Build and run 或者直接按F9,即可查看輸出。這種方法創建C/C++控制臺程序,優點是輕便,文件最后只生成三個,源代碼.c文件,.o文件還有exe文件,缺點是不支持調試。適合輕量級開發
第二種方法是新建一個工程,在菜單欄點擊 File – New – Project…,彈出的界面選擇 Console Application ,然后選擇代碼類型和文件保存目錄,之后它會生成一個該項目的文件夾,然后有一個main.c(main.cpp)文件,在這個文件中編寫代碼。這個項目中的核心文件是.cbp,還會生成很多從屬文件,優點是調試方便,可以用Debug單步調試,缺點是生成文件多,適合大型項目開發。
本次操作系統課程設計均是用第二種方式生成C++項目編寫。

1-2 創建進程

1.創建一個C++項目,將指導書中的1-2代碼復制到main.cpp文件中,然后編譯運行
2.按照代碼中的注釋提示修改代碼,看有什么不同,共有兩處修改
3.通過查閱相關資料分析為何會出現這樣的結果

關鍵代碼

BOOL bCreateOK=::CreateProcess(szFilename, // 產生這個 EXE 的應用程序的名稱szCmdLine, // 告訴其行為像一個子進程的標志NULL, // 缺省的進程安全性NULL, // 缺省的線程安全性FALSE, // 不繼承句柄CREATE_NEW_CONSOLE, // 使用新的控制臺NULL, // 新的環境NULL, // 當前目錄&si, // 啟動信息&pi) ; // 返回的進程信息

1-3 父子進程的簡單通信及終止進程

1.創建一個C++項目,將指導書中的1-3代碼復制到main.cpp文件中,然后按F9查看運行結果
2.根據注釋修改代碼,查看結果
3.查閱資料,分析原因

關鍵代碼

// 決定其行為是父進程還是子進程if (argc>1 && :: strcmp(argv[1], "child" ) == 0){Child() ;}else{Parent() ;}

實驗結果與分析

1-1 編寫基本的 Win32 Consol Application

運行結果:

return是返回值,如果越界就會返回一個數,后邊execution time 是 C/C++控制臺程序執行的時間。

1-2 創建進程

不修改的運行結果

會生成5個子進程,且0號進程結束后其余進程不消失
第一次修改
nClone=0;
結果和原代碼一樣
第二次修改

if (argc > 1){ // 從第二個參數中提取克隆 ID:: sscanf(argv[1], "%d", &nClone) ; } //第二次修改:nClone=0; nClone = 0;


結果無限生成子進程。

結果分析:
生成子進程的過程是父進程生成一個子進程,然后子進程再“克隆”自己生成一個子進程,如此反復,直到到達代碼中規定的 const int c_nCloneMax=5;為止。

重點在于這三句代碼,當父進程生成子進程的時候,會給子進程傳遞參數,傳參的內容就是 代碼中的 szCmdLine 字符串,例如0號主進程會給子進程傳遞2個參數,第一個參數是 szFilename 是從主進程信息中獲取,第二個參數就是 nClone,用來控制生成的克隆數量。
分析兩次修改
第一次修改是在

if (argc > 1) { :: sscanf(argv[1], "%d", &nClone) ;}

之前,執行nClone=0;將nClone的量置為0,但是之后會判斷參數數量,如果傳進來大于一個參數,就會把傳進來的第二個參數賦值給nClone,也就說子進程的nClone最后的值是它的父進程傳進來的值,第一次修改的nClone=0;會被sscanf()覆蓋掉。
而第二次修改則是在if判斷之后,if判斷中將父進程傳進來的參數賦值給nClone,然后第二次修改則會覆蓋掉if中的賦值,將nClone置為0,所以說,nClone的值最后就是0,比較nClone < c_nCloneMax會恒成立,然后就會無限生成子進程,同時子進程的nClone參數永遠都是1

1-3 父子進程的簡單通信及終止進程


然后在父進程中輸入回車,主進程結束,同時子進程也消失。
修改代碼
修改代碼之后,子進程不出現,只有主進程
結果分析:
修改了WaitForSingleObject(hMutexSuicide,INFINITE) ;這句代碼的第二個參數,將INFINITE改成了0,WaitForSingleObject()函數的第二參數是等待時間,如果超過這個時間(ms),不管互斥體是否可用都繼續運行。而INFINITE在C++表示的意思是正無窮,實際上是一個宏定義 #define INFINITE 0xFFFFFFFF,意思是表示一個非常大的數,所以子程序會一直等互斥體可用,然后再結束。
第二次修改

這個步驟原理和1-2類似,都是識別命令行參數,不再贅述

小結與心得體會

本驗證性實驗熟悉了CreateProcess()函數的大概用法,同時理解了控制臺程序傳參的過程。通過簡單的修改nClone的值,實現完全不同的效果,同時再次認識到代碼設計過程中,要多多注意邏輯錯誤.同時了解了互斥程序體的使用,利用WaitForSingleObject()和ReleaseMutex()實現互斥操作。收獲良多。=w=

源代碼

1-1 編寫基本的 Win32 Consol Application

#include <iostream> using namespace std;int main() {cout << "Hello, Win32 Consol Application" << endl;return 0; }

1-2 創建進程

#include <windows.h> #include <iostream> #include <cstdio> // 創建傳遞過來的進程的克隆過程并賦于其 ID 值 void StartClone(int nCloneID) { // 提取用于當前可執行文件的文件名TCHAR szFilename[MAX_PATH] ; /*字符串類型*///第一個參數為句柄,NULL則指向當前程序。第二個參數用于存放地址的指針,第三個參數,系統自帶的宏定義。不用管.GetModuleFileName(NULL, szFilename, MAX_PATH); // 格式化用于子進程的命令行并通知其 EXE 文件名和克隆 IDTCHAR szCmdLine[MAX_PATH];sprintf(szCmdLine,"\"%s\" %d",szFilename,nCloneID); // 用于子進程的 STARTUPINFO 結構STARTUPINFO si;ZeroMemory(&si, sizeof(si) ) ; /*用0填充*//*包含STARTUPINFO結構中的字節數.如果Microsoft將來擴展該結構,它可用作版本控制手段,應用程序必須將cb初始化為sizeof(STARTUPINFO)*/si.cb = sizeof(si) ; // 必須是本結構的大小5 // 返回的用于子進程的進程信息PROCESS_INFORMATION pi; // 利用同樣的可執行文件和命令行創建進程,并賦于其子進程的性質BOOL bCreateOK=::CreateProcess(szFilename, // 產生這個 EXE 的應用程序的名稱szCmdLine, // 告訴其行為像一個子進程的標志NULL, // 缺省的進程安全性NULL, // 缺省的線程安全性FALSE, // 不繼承句柄CREATE_NEW_CONSOLE, // 使用新的控制臺NULL, // 新的環境NULL, // 當前目錄&si, // 啟動信息&pi) ; // 返回的進程信息 // 對子進程釋放引用if (bCreateOK){/*關閉一個內核對象*/CloseHandle(pi.hProcess) ;CloseHandle(pi.hThread) ;} } int main(int argc, char* argv[] ) { // 確定派生出幾個進程,及派生進程在進程列表中的位置int nClone=0; //修改語句:int nClone; //第一次修改:nClone=0;//nClone=0;if (argc > 1){ // 從第二個參數中提取克隆 ID:: sscanf(argv[1], "%d", &nClone) ;} //第二次修改:nClone=0; /*此處修改無限生成子進程*///nClone = 0; // 顯示進程位置std :: cout << "Process ID:" << :: GetCurrentProcessId()<< ", Clone ID:" << nClone<< std :: endl; // 檢查是否有創建子進程的需要const int c_nCloneMax=5;if (nClone < c_nCloneMax){ // 發送新進程的命令行和克隆號StartClone(++nClone) ;} // 等待響應鍵盤輸入結束進程getchar();return 0; }

1-3 父子進程的簡單通信及終止進程

# include <windows.h> # include <iostream> # include <cstdio> static LPCTSTR g_szMutexName = "w2kdg.ProcTerm.mutex.Suicide" ; // 創建當前進程的克隆進程的簡單方法 void StartClone() { // 提取當前可執行文件的文件名TCHAR szFilename[MAX_PATH] ;GetModuleFileName(NULL, szFilename, MAX_PATH) ; // 格式化用于子進程的命令行,字符串“child”將作為形參傳遞給子進程的 main 函數TCHAR szCmdLine[MAX_PATH] ; //實驗 1-3 步驟 3:將下句中的字符串 child 改為別的字符串,重新編譯執行,執行前請先保存已經//完成的工作sprintf(szCmdLine, "\"%s\" child", szFilename) ; // 子進程的啟動信息結構STARTUPINFO si;ZeroMemory(&si,sizeof(si)) ;si.cb = sizeof(si) ; // 應當是此結構的大小 // 返回的用于子進程的進程信息PROCESS_INFORMATION pi; // 用同樣的可執行文件名和命令行創建進程,并指明它是一個子進程BOOL bCreateOK=CreateProcess(szFilename, // 產生的應用程序的名稱 (本 EXE 文件)szCmdLine, // 告訴我們這是一個子進程的標志NULL, // 用于進程的缺省的安全性NULL, // 用于線程的缺省安全性FALSE, // 不繼承句柄CREATE_NEW_CONSOLE, //創建新窗口NULL, // 新環境NULL, // 當前目錄&si, // 啟動信息結構&pi ) ; // 返回的進程信息 // 釋放指向子進程的引用if (bCreateOK){CloseHandle(pi.hProcess) ;CloseHandle(pi.hThread) ;} } void Parent() { // 創建“自殺”互斥程序體HANDLE hMutexSuicide=CreateMutex(NULL, // 缺省的安全性TRUE, // 最初擁有的7g_szMutexName) ; // 互斥體名稱if (hMutexSuicide != NULL){ // 創建子進程std :: cout << "Creating the child process." << std :: endl;StartClone() ; // 指令子進程“殺”掉自身std :: cout << "Telling the child process to quit. "<< std :: endl; //等待父進程的鍵盤響應getchar() ; //釋放互斥體的所有權,這個信號會發送給子進程的 WaitForSingleObject 過程ReleaseMutex(hMutexSuicide) ; // 消除句柄CloseHandle(hMutexSuicide) ;} } void Child() { // 打開“自殺”互斥體HANDLE hMutexSuicide = OpenMutex(SYNCHRONIZE, // 打開用于同步FALSE, // 不需要向下傳遞g_szMutexName) ; // 名稱if (hMutexSuicide != NULL){ // 報告我們正在等待指令std :: cout <<"Child waiting for suicide instructions. " << std :: endl;//子進程進入阻塞狀態,等待父進程通過互斥體發來的信號/*INFINITE表示最大,參數表為對象句柄和毫秒數*/WaitForSingleObject(hMutexSuicide,INFINITE) ;//WaitForSingleObject(hMutexSuicide,0);//WaitForSingleObject(hMutexSuicide,5000); //實驗 1-3 步驟 4:將上句改為 WaitForSingleObject(hMutexSuicide, 0) ,重新編譯執行 // 準備好終止,清除句柄std :: cout << "Child quiting." << std :: endl;CloseHandle(hMutexSuicide) ;} } int main(int argc, char* argv[] ) { // 決定其行為是父進程還是子進程if (argc>1 && :: strcmp(argv[1], "child" ) == 0){Child() ;}else{Parent() ;}return 0; }

總結

以上是生活随笔為你收集整理的操作系统课设之Windows 进程管理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。