演示作业的使用及获取统计信息
演示作业的使用及获取统计信息
文章目录
- 演示作业的使用及获取统计信息
- 演示作业的使用及获取统计信息
演示作业的使用及获取统计信息
/*
演示作业的使用及获取统计信息
*/#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);//枚举作业对象中的进程IDEnumProcessIdsInJob(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;
}
演示完毕,大家可以上机实验