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;
}

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

相关推荐
蓝田~1 小时前
观察者模式和订阅模式
windows·观察者模式
梓仁沐白7 小时前
ubuntu+windows双系统切换后蓝牙设备无法连接
windows·ubuntu
九鼎科技-Leo11 小时前
什么是 WPF 中的依赖属性?有什么作用?
windows·c#·.net·wpf
Yang.9914 小时前
基于Windows系统用C++做一个点名工具
c++·windows·sql·visual studio code·sqlite3
我不瘦但很逗14 小时前
Windows下使用DBeaver连接云数据库(MySQL)
数据库·windows
ashane131415 小时前
Java list
java·windows·list
万里沧海寄云帆15 小时前
Word 插入分节符页码更新问题
windows·microsoft·word
dot.Net安全矩阵16 小时前
.NET 通过模块和驱动收集本地EDR的工具
windows·安全·web安全·.net·交互
编程修仙18 小时前
Collections工具类
linux·windows·python
程序员小羊!19 小时前
高级 SQL 技巧讲解
windows