进程管理
实验内容
通过对Windows进程编程,熟悉操作系统的基本概念、熟悉进程的概念,理解Windows进程的编程,Windows进程的结构。
实验环境
操作系统:Windows 11
应用软件:CodeBlocks
实验步骤
任务一:
// prochandle项目
#include<Windows.h>
#include<wchar.h>
#include<stdio.h>
#include<iostream>
using namespace std;
//确定自己的优先权的简单应用程序
int main()
{
//从当前过程中提取句柄
HANDLE hProcessThis=::GetCurrentProcess();
//请求内核提供该过程所属的优先权类
DWORD dwPriority=::GetPriorityClass(hProcessThis);
//发出消息,为用户描述该类
::cout<<"current process priority:";
switch(dwPriority)
{
case HIGH_PRIORITY_CLASS:
::cout<<"High";
break;
case NORMAL_PRIORITY_CLASS:
::cout<<"Normal";
break;
case IDLE_PRIORITY_CLASS:
::cout<<"Idle";
break;
case REALTIME_PRIORITY_CLASS:
::cout<<"Realtime";
break;
default:
::cout<<"<unknown>";
break;
}
::cout<<::endl;
getchar();
return 0;
}
任务二:
#include<Windows.h>
#include<wchar.h>
#include <tlhelp32.h>
#include<stdio.h>
#include<iostream>
using namespace std;
//当在用户模式机内模式下都提供所耗时间时,在内核模式下进行所耗时间的位计算的帮助方法
DWORD GetKernelModePercentage(const FILETIME& ftKernel,const FILETIME& ftUser)
{
//将FILETIME结构转化为位整数
ULONGLONG qwKernel = (((ULONGLONG)ftKernel.dwHighDateTime)
<<32) + ftKernel.dwLowDateTime;
ULONGLONG qwUser = (((ULONGLONG)ftUser.dwHighDateTime)
<<32) + ftUser.dwLowDateTime;
//将消耗时间相加,然后计算消耗在内模式下的时间百分比
ULONGLONG qwTotal = qwKernel + qwUser;
DWORD dwPct = (DWORD)(((ULONGLONG)100 * qwKernel)/qwTotal);
return(dwPct);
}
//以下是将当前运行过程名和消耗在内模式下的时间百分数都显示出来的应用程序
int main()
{
//对当前系统中运行的过程拍取"快照"
HANDLE hSnapshot = ::CreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS, //提取当前过程
0); //如果是当前过程,就将其忽略
//初始化过程入口
PROCESSENTRY32 pe;
::ZeroMemory(&pe,sizeof(pe));
pe.dwSize = sizeof(pe);
BOOL bMore = ::Process32First(hSnapshot,&pe);
while(bMore)
{
//打开用于读取的过程
HANDLE hProcess = ::OpenProcess(
PROCESS_QUERY_INFORMATION, //指明要得到信息
FALSE, //不必继承这一句柄
pe.th32ProcessID); //要打开的过程
if(hProcess!=NULL)
{
//找出进程的时间
FILETIME ftCreation, ftKernelMode,ftUserMode,ftExit;
::GetProcessTimes(
hProcess, //所感兴趣的进程
&ftCreation, //进程的启动时间
&ftExit, //结束时间(如果有的话)
&ftKernelMode, //在内核模式下消耗的时间
&ftUserMode); //在用户模式下消耗的时间
//计算内核模式消耗的时间百分比
DWORD dwPctKernel = ::GetKernelModePercentage(
ftKernelMode, //在内核模式上消耗的时间
ftUserMode); //在用户模式下消耗的时间
//向用户显示进程的某些信息
::cout << "process ID:"<< pe.th32ProcessID
<< ",EXE file:" << pe.szExeFile
<< ", % in Kernel mode:" << dwPctKernel << endl;
//消除句柄
::CloseHandle(hProcess);
}
//转向下一个进程
bMore = ::Process32Next(hSnapshot,&pe);
}
getchar();
return 0;
}
运行结果
任务一
实验分析
1.<Windows.h>:Windows平台的API函数和类型定义。
2.<wchar.h>:用于宽字符操作
3.使用CreateToolhelp32Snapshot函数获取系统中当前所有进程的快照。
4.对每个进程,使用OpenProcess函数打开它,并通过GetProcessTimes函数获取该进程的创建时间、退出时间、内核模式时间和用户模式时间
5.使用CloseHandle关闭不再需要的句柄
经查询:
当运行在用户模式的应用程序需要进行输入输出、申请内存等比较底层的操作时,就必须调用操作系统提供的API函数,从而进入内核模式。操作完成后,继续执行应用程序的代码,就又回到了用户模式。这种在两种模式之间的切换是操作系统实现资源管理、进程调度和安全性控制的关键机制。
实验小结
1.通过任务一,了解了如何获取进程句柄、查询进程优先权类,
2.通过实验二了解到了如何成功地展示了如何使用Windows API来获取系统中运行进程的信息,并计算每个进程在内核模式下所消耗时间的百分比。实验代码使用了CreateToolhelp32Snapshot、Process32First、Process32Next等函数来遍历进程,并通过OpenProcess和GetProcessTimes函数获取每个进程的详细信息。之后,利用自定义的GetKernelModePercentage函数计算内核模式时间的百分比,并将结果输出到控制台。