實驗一:進程控制。
1、實驗目的:通過在Windows 任務管理器中對進程進行相應的管理操作,熟悉操作系統進程管理的概念,學習觀察操作系統運行的動態性能;學習創建進程、觀察進程和終止進程的程序設計方法;理解Windows進程的“一生”。
2、實驗內容:
(1)
使用任務管理器查看、終止進程;
(2)
創建進程;
(3)
獲取進程運行信息,改變進程優先級;
(4)
終止進程。
3、實驗步驟:
程序一:創建進程
(1)
父進程創建子進程,子進程創建下一個子進程;
(2)
創建子進程時將子進程序號作為命令行參數傳給子進程,子進程將序號加一后繼續創建下一個子進程;
(3)
限制創建子進程的最大個數;
(4)
進程在終止之前暫停一下,輸入一個字符后,進程結束,以便觀察。
思考題:
(1)
運行后在系統任務管理器中查看所創建進程映像名,有什么規律?
(2)
父子進程使用同一程序,具體是如何進行區別的?
(3)
不同進程的克隆ID是如何獲取到的?
(4)
如果在克隆ID為0的進程中創建克隆ID為1-8的進程,應該如何修改程序?
程序二:查看進程運行信息
(1)
在main()函數中獲取當前進程ID,獲取當前進程版本信息;
(2)
獲取操作系統版本信息;
(3)
獲取當前進程優先級;
(4)
如果操作系統版本>=Windows XP,并且當前進程優先級不是HIGH_PRIORITY_CLASS,將當前進程優先級改為HIGH_PRIORITY_CLASS;
(5)
顯示改變后的進程優先級。
思考題:
(1)
進程的優先級存放在哪里?
程序三:終止進程
(1)
在程序一的基礎上,當前進程每創建一個新進程,增加一個參數,用以表示當前進程的進程ID;
(2)
新進程運行時獲取父進程的進程ID;
(3)
在指定的進程中獲取父進程的句柄;
(4)
在指定的進程中終止父進程。
思考題:
(1)
一個進程終止其父進程所需的句柄是如何獲取的?
(2)
Windows下的進程ID和進程句柄有什么區別?
// 實驗一創建進程.cpp : Defines the entry point for the console application.
//
//#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <stdio.h>
//創建子進程,與父進程執行相同的程序。
void StartClone(int nCloneID)
{
// 獲取當前進程的可執行文件名。
TCHAR szFilename[MAX_PATH] ;
:: GetModuleFileName(
NULL, //一個模塊的句柄。模塊句柄跟一般的句柄不一樣,
//模塊句柄指向的就是EXE和DLL等在內存的位置。
//如果該參數為NULL,該函數返回該應用程序全路徑。
szFilename,
MAX_PATH) ;
// 格式化用于創建新進程的命令行,包括EXE文件名和克隆ID
TCHAR szCmdLine[MAX_PATH];
:: sprintf(szCmdLine,"\"%s\"%d",szFilename,nCloneID);
// 用于新進程的STARTUPINFO結構
STARTUPINFO si;
:: ZeroMemory(reinterpret_cast <void*> (&si) , sizeof(si) ) ;
si.cb = sizeof(si) ;
// 必須是本結構的大小
// 返回的用于新進程的進程信息
PROCESS_INFORMATION pi;
// 使用同一可執行文件和帶有克隆ID的命令行創建新進程。
BOOL bCreateOK=::CreateProcess(
szFilename,
// 新進程的可執行文件名
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[] )
{
// 進程的克隆ID
int nClone(0) ;
//第一個進程argc為1,以后每個進程命令行有兩個參數,
//其中第二個是克隆ID。
if (argc > 1)
{
// 從第二個參數中提取克隆ID
:: sscanf(argv[1] , "%d" , &nClone) ;
}
// 顯示進程的克隆ID
std :: cout << "Process ID:" << :: GetCurrentProcessId()
<< ", Clone ID:" << nClone
<< std :: endl;
// 創建新進程,其nClone為1-8
const int c_nCloneMax=8;
if (nClone < c_nCloneMax)
{
:: Sleep(3000) ;
StartClone(++nClone) ;
}
// 在終止之前暫停一下。輸入一個字符后,程序結束,以便觀察。
std::cout<<"input a char:";
getchar();
std::cout<<"I'm stopped ... Bye-Bye";
:: Sleep(1000) ;
return 0;
}
// 實驗一終止進程.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <stdio.h>
//創建子進程,與父進程執行相同的程序。
void StartClone(int nCloneID)
{
// 獲取當前進程的可執行文件名取當前進程的可執行文件名
TCHAR szFilename[MAX_PATH] ;
:: GetModuleFileName(
NULL, //一個模塊的句柄。模塊句柄跟一般的句柄不一樣,
//模塊句柄指向的就是EXE和DLL等在內存的位置。
//如果該參數為NULL,該函數返回該應用程序全路徑。
szFilename,
MAX_PATH) ;
// 格式化用于創建新進程的命令行,包括EXE文件名、克隆ID和當前進程的ID。
TCHAR szCmdLine[MAX_PATH];
:: sprintf(szCmdLine,"\"%s\"%d %d",szFilename,nCloneID,::GetCurrentProcessId());
// 用于新進程的STARTUPINFO結構
STARTUPINFO si;
:: ZeroMemory(reinterpret_cast <void*> (&si) , sizeof(si) ) ;
si.cb = sizeof(si) ;
// 必須是本結構的大小
// 返回的用于新進程的進程信息
PROCESS_INFORMATION pi;
// 使用同一可執行文件和帶有克隆ID、當前進程ID的命令行創建新進程。
BOOL bCreateOK=::CreateProcess(
szFilename,
// 新進程的可執行文件名
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[] )
{
// 進程的克隆ID
int nClone(0) ;
// 保存父進程的進程ID
int ProcessId(0);
//第一個進程argc為1,以后每個進程命令行有3個參數,
//其中第3個是父進程ID。
if (argc > 1)
{
// 從第2個參數中提取克隆ID
:: sscanf(argv[1] , "%d" , &nClone) ;
// 從第3個參數中提取父進程ID
:: sscanf(argv[2] , "%d" , &ProcessId) ;
}
// 顯示進程ID和克隆ID
std :: cout << "Process ID:" << :: GetCurrentProcessId()
<< ", Clone ID:" << nClone
<< std :: endl;
//終止父進程
if(nClone==3)
{
::TerminateProcess(OpenProcess(PROCESS_TERMINATE,FALSE,ProcessId),1);
std::cout<<"Terminate Process Clone ID=2"
<< std :: endl;
}
// 創建新進程,其nClone為1-8
const int c_nCloneMax=8;
if (nClone < c_nCloneMax)
{
:: Sleep(2000) ;
StartClone(++nClone) ;
}
// 在終止之前暫停一下。輸入一個字符后,程序結束,以便觀察。
std::cout<<"input a char:";
getchar();
std::cout<<"I'm stopped ... Bye-Bye";
:: Sleep(1000) ;
return 0;
}
// 實驗一查看進程運行信息.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <iostream>
// 進程和操作系統版本信息的簡單示例
int main(int argc, char* argv[])
{
// 獲取這個進程的ID號
DWORD dwIdThis=:: GetCurrentProcessId();
// 獲得和顯示這一進程所需的版本,也可以用0表示當前進程
DWORD dwVerReq=:: GetProcessVersion(dwIdThis);
WORD wMajorReq=(WORD)(dwVerReq>16) ;
WORD wMinorReq=(WORD)(dwVerReq & 0xffff) ;
std :: cout << "Process ID: "<< dwIdThis
<<", requires OS: " << wMajorReq <<"."
<< wMinorReq << std :: endl ;
// 設置版本信息的數據結構,以便保存操作系統的版本信息
OSVERSIONINFOEX osvix;
:: ZeroMemory(&osvix, sizeof(osvix) ) ;
osvix.dwOSVersionInfoSize=sizeof(osvix) ;
// 獲取版本信息和顯示
:: GetVersionEx(reinterpret_cast < LPOSVERSIONINFO > (&osvix)) ;
std :: cout << "Running on OS:" << osvix.dwMajorVersion <<"."
<< osvix.dwMinorVersion << std :: endl;
//顯示當前進程的優先級
//GetCurrentProcess()獲得的句柄只是一個偽句柄,只能在我們的進程中才能代表當前進程的句柄,
//事實上這個函數目前只是簡單的返回-1這個值。
DWORD dwProcessP=::GetPriorityClass(GetCurrentProcess());
std::cout<<"Current process priority is :";
switch(dwProcessP)
{
case HIGH_PRIORITY_CLASS:
std::cout<<"High";
break;
case NORMAL_PRIORITY_CLASS:
std::cout<<"Normal";
break;
case IDLE_PRIORITY_CLASS:
std::cout<<"Idle";
break;
case REALTIME_PRIORITY_CLASS:
std::cout<<"Realtime";
break;
default:
std::cout<<"<unknow>";
break;
}
std::cout<<std::endl;
// 如果是NTS(Windows 2000) 系統,則提高其優先權
if (osvix.dwPlatformId==VER_PLATFORM_WIN32_NT && osvix.dwMajorVersion >= 5)
{
if(dwProcessP!=HIGH_PRIORITY_CLASS)
{
// 如果當前優先級不是high,則改變優先級為high
:: SetPriorityClass(
:: GetCurrentProcess() ,
HIGH_PRIORITY_CLASS);
//報告給用戶
DWORD dwProcessP = GetPriorityClass(GetCurrentProcess());
std::cout<<"The Process priority have been changed to ";
switch(dwProcessP)
{
case HIGH_PRIORITY_CLASS:
std::cout<<"High";
break;
case NORMAL_PRIORITY_CLASS:
std::cout<<"Normal";
break;
case IDLE_PRIORITY_CLASS:
std::cout<<"Idle";
break;
case REALTIME_PRIORITY_CLASS:
std::cout<<"Realtime";
break;
default:
std::cout<<"<unknow>";
break;
}
std::cout<<std::endl;
}
}
return 0;
}
本站文章版權歸原作者及原出處所有 。內容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負責,本站只提供參考并不構成任何投資及應用建議。本站是一個個人學習交流的平臺,網站上部分文章為轉載,并不用于任何商業目的,我們已經盡可能的對作者和來源進行了通告,但是能力有限或疏忽,造成漏登,請及時聯系我們,我們將根據著作權人的要求,立即更正或者刪除有關內容。本站擁有對此聲明的最終解釋權。