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

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

相关推荐
Flame_Cyclone7 小时前
编写XBOX控制器实现鼠标键盘输入
c++·windows·win32·xbox·控制器模拟键盘鼠标
CHHC188010 小时前
NetCore DynamicExpresso 动态表达式使用例子
windows
奔跑的呱呱牛11 小时前
Windows和Mac命令窗快速打开文件夹
windows·macos
小奥超人12 小时前
批量操作Excel的四个方法(求和、移动、对比、合并)
windows·经验分享·microsoft·excel·办公技巧
シ風箏14 小时前
MinIO【部署 02】Linux集群版本及Windows单机版、单机多目录版、分布式版(cmd启动脚本及winsw脚本分享)
linux·windows·分布式·minio·文件存储系统
星空爱忆14 小时前
在 Mac 上安装虚拟机怎么样,安装虚拟机与直接安装 Windows 系统有区别吗?
windows·mac·parallels
搁浅°87917 小时前
Collection
java·开发语言·windows
DynamicsAgg18 小时前
Windows技术栈企业基础底座(1)-为基于Windows的Nginx安装证书
运维·windows·nginx
V_fanglue370519 小时前
qmt量化交易策略小白学习笔记第60期【qmt编程之期权数据--基于BS模型计算欧式期权隐含波动率--内置Python】
开发语言·windows·笔记·python·学习·区块链
奋斗的小青年I1 天前
一文秒懂ipconfig、ifconfig和ip addr的区别与应用
服务器·网络·windows·网络协议·tcp/ip·系统架构·云计算