进程管理
实验内容
通过对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;
//当在用户模式机内模式下都提供所耗时间时,在内核模式下进行所耗时间的64位计算的帮助方法
DWORD GetKernelModePercentage(const FILETIME& ftKernel,const FILETIME& ftUser)
{
//将FILETIME结构转化为64位整数
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关闭不再需要的句柄
经查询:
用户模式,也被称为用户空间,是Linux或Windows等操作系统中应用程序运行的模式。在此模式下,应用程序与用户交互,接收用户输入,并执行相应的操作。应用程序的虚拟地址空间是专用的,因此一个应用程序无法更改属于其他应用程序的数据。每个应用程序都隔离运行,如果一个应用程序发生故障,故障通常仅局限于该应用程序,其他应用程序和操作系统不会受到该故障的影响。用户模式运行的应用程序受到操作系统的限制相对较少,可以自由地使用系统资源,但不能直接访问系统硬件资源和系统数据,需要通过系统调用接口向操作系统请求服务。这种设计有助于保护系统免受恶意软件或错误程序的影响。
内核模式,也被称为核心空间或内核空间,是操作系统运行的模式。在此模式下,操作系统处理系统级别的任务,例如管理硬件资源、调度进程、分配内存等。内核模式运行的操作系统具有更高的权限,可以访问系统中的所有资源,包括硬件设备和内核代码区域。因此,内核模式下的操作系统可以通过驱动程序接口向硬件设备请求服务,执行特权级指令,对任何I/O设备有全部的访问权,还能够访问任何虚地址和控制虚拟内存硬件。由于内核模式下有更高的执行权限,任何在此模式下运行的代码都必须非常可靠,因为错误可能导致系统崩溃或安全问题。
当运行在用户模式的应用程序需要进行输入输出、申请内存等比较底层的操作时,就必须调用操作系统提供的API函数,从而进入内核模式。操作完成后,继续执行应用程序的代码,就又回到了用户模式。这种在两种模式之间的切换是操作系统实现资源管理、进程调度和安全性控制的关键机制。
实验小结
1.通过任务一,了解了如何获取进程句柄、查询进程优先权类,
2.通过实验二了解到了如何成功地展示了如何使用Windows API来获取系统中运行进程的信息,并计算每个进程在内核模式下所消耗时间的百分比。实验代码使用了CreateToolhelp32Snapshot、Process32First、Process32Next等函数来遍历进程,并通过OpenProcess和GetProcessTimes函数获取每个进程的详细信息。之后,利用自定义的GetKernelModePercentage函数计算内核模式时间的百分比,并将结果输出到控制台。