windows 核心编程第五章:演示作业的使用及获取统计信息

演示作业的使用及获取统计信息

演示作业的使用及获取统计信息

文章目录


演示作业的使用及获取统计信息

cpp 复制代码
/*
演示作业的使用及获取统计信息
*/

#include <stdio.h>
#include <Windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <malloc.h> // for _alloca函数
#include <locale.h> 	


void EnumProcessIdsInJob(HANDLE hJob);//获取作业中当前的进程ID集
void StartRestrictedProcess();//利用作业对象对进程进程管理的演示

int _tmain()
{
	_tsetlocale(LC_ALL, TEXT("chs"));
	StartRestrictedProcess();
	return (0);
}
//获取作业中当前的进程ID集
void EnumProcessIdsInJob(HANDLE hJob)
{
	//先假设作业中的进程不会超过10个
	const int MAM_PROCESS_IDS = 10;

	//计算结构体和ID集所需的控件大小
	DWORD cb = sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) + 
		(MAM_PROCESS_IDS - 1) * sizeof(DWORD);

	//分配内存,注意_allocal是在栈(而不是堆上分配的,所有不需要释放)
	PJOBOBJECT_BASIC_PROCESS_ID_LIST pjobpil =
		(PJOBOBJECT_BASIC_PROCESS_ID_LIST)_alloca(cb);

	//估计最多的线程数
	pjobpil->NumberOfAssignedProcesses = MAM_PROCESS_IDS;

	//查询
	QueryInformationJobObject(hJob, JobObjectBasicProcessIdList, pjobpil, cb, &cb);

	//显示进程ID集
	for (DWORD x = 0; x < pjobpil->NumberOfProcessIdsInList; x++)
	{
		_tprintf(TEXT("process %d(ID = %d)\n"), x + 1, pjobpil->ProcessIdList[x]);
	}
}
//利用作业对象对进程进程管理的演示
void StartRestrictedProcess()
{
	//检查进程是否已经包含在作业中
	// 如果已经关联。就没犯法在换到另外一个作业对象中去

	/*屏蔽测试
	BOOL bInJob = FALSE;
	IsProcessInJob(GetCurrentProcess(), NULL, &bInJob);
	if (bInJob)
	{
		_tprintf(_T("Process already in a job\n"));
		return;
	}*/

	//创建作业内核对象
	HANDLE hJob = CreateJobObject(NULL,
		TEXT("MyRestrictedProcessJob"));

	//在作业中放入线程对象的一些限制规则
	//首先,设置基本限制
	JOBOBJECT_BASIC_LIMIT_INFORMATION jobli = { 0 };

	//进程总是运行在"空闲"优先级
	jobli.PriorityClass = IDLE_PRIORITY_CLASS;

	//该作业对象在用户模式下不能超过1ms的cpu时间
	jobli.PerJobUserTimeLimit.QuadPart = 1000 * 10000I64;
	//10000tick = 10000*100ns = 1ms
	//这里只增加了两个限制
	jobli.LimitFlags =
		JOB_OBJECT_LIMIT_PRIORITY_CLASS |
		JOB_OBJECT_LIMIT_JOB_TIME;

	SetInformationJobObject(hJob, JobObjectBasicLimitInformation,
		&jobli, sizeof(jobli));

	//其次,设置UI限制
	JOBOBJECT_BASIC_UI_RESTRICTIONS jobuir;
	jobuir.UIRestrictionsClass = JOB_OBJECT_UILIMIT_NONE;//初始化为0

	//进程不能访问用户对象(比如窗口句柄)
	jobuir.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;
	//进程不能关闭系统
	jobuir.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_EXITWINDOWS;

	SetInformationJobObject(hJob, JobObjectBasicUIRestrictions, &jobuir, sizeof(jobuir));

	//创建子进程并加入作业对象中
	//Note:进程被创建后,其线程要立刻挂起。再加入作业对象前,不能指向任何代码
	//这里作业对象的要求,否则,进程指向的那部分代码可能就不受作业对象的限制

	STARTUPINFO si = { sizeof(si) };
	PROCESS_INFORMATION pi;
	TCHAR szCmdLine[8];
	_tcscpy_s(szCmdLine, _countof(szCmdLine), TEXT("CMD"));

	BOOL bResult = CreateProcess(NULL, szCmdLine, NULL, NULL, FALSE,
		CREATE_SUSPENDED | CREATE_NEW_CONSOLE,
		NULL, NULL, &si, &pi);

	//将子进程加入到作业对象中
	//注意:当创建子进程时,子进程会自动加入到父进程所父的作业对象中

	AssignProcessToJobObject(hJob, pi.hProcess);

	//限制可以回复子进程的主线程,开始执行代码
	ResumeThread(pi.hThread);
	CloseHandle(pi.hThread);

	//枚举作业对象中的进程ID
	EnumProcessIdsInJob(hJob);

	//等待子进程结束或者作业对象所分配的cpu时间被用完
	HANDLE h[2];
	h[0] = pi.hProcess;
	h[1] = hJob;

	DWORD dw = WaitForMultipleObjects(2, h, FALSE, INFINITE);
	switch (dw - WAIT_OBJECT_0)
	{
	case 0:
		_tprintf(_T("The process has terminated...\n"));
		break;
	case 1:
		_tprintf(_T("All of the job's allotted CPU time was used...\n"));
		break;
	}

	FILETIME CreationTime;
	FILETIME ExitTime;
	FILETIME KernelTime;
	FILETIME UserTime;
	TCHAR szInfo[MAX_PATH];

	GetProcessTimes(pi.hProcess, &CreationTime, &ExitTime,
		&KernelTime, &UserTime);
	StringCchPrintf(szInfo, _countof(szInfo),
		TEXT("Kernel = %u|User = %u\n"),
		KernelTime.dwLowDateTime / 10000,
		UserTime.dwLowDateTime / 10000);

	CloseHandle(pi.hProcess);
	CloseHandle(hJob);

	_tprintf(szInfo);

	_tsystem(_T("pause"));
	return;
}

演示完毕,大家可以上机实验

相关推荐
jyOverQ8 小时前
ChatGPT Windows 客户端点击无反应、有进程却没窗口?一次 MSIX 非系统盘启动卡死的完整排查
windows·chatgpt
还是大剑师兰特11 小时前
MySQL8.0 Windows完整安装教程
windows·mysql·大剑师
redfred13 小时前
HandBrake 使用教程:开源视频压缩工具 视频太大压缩 MKV转MP4 批量转码 硬件加速 Windows/macOS/Linux
windows·开源·音视频
kakakahahahaha13 小时前
【Windows】C盘拒绝访问0x80070005的7步排查
windows·电脑·内容运营·软件需求
万年咸鱼15 小时前
Java ArrayList 详解:原理、用法与实战
java·开发语言·windows
奈斯先生Vector16 小时前
本地图片识别怎么接入多模态 AI?用 Python API 理解 GPT-4o Vision 的真实工作流
开发语言·人工智能·windows·python·网络协议·http·aigc
yyywxk16 小时前
ChatGPT/Codex Windows 桌面版“幽灵会话”问题:网页端已删除,桌面端仍显示且无法删除/归档
windows·chatgpt
万年咸鱼17 小时前
Java List 接口详解:从基础到实战
java·windows·list
Neighbor_OldY18 小时前
【实战复盘】RDP暴力破解与内网横向移动溯源:Windows全套排查命令与事件ID硬核解析
运维·windows·web安全
深念Y18 小时前
Windows 11 工具链部署与 SSH 踩坑笔记
windows·笔记·ssh