第五章 作业
本章内容
5.1 对作业中的进程施加限制
5.2 将进程放入作业中
5.3 终止作业中的所有进程
5.4 作业通知
5.5 Job Lab示例程序
有时候为了完成某些任务需要执行一组进程,需要将一组进程作为一个组来管理。并且可以加以限制。
windows提供一个job内核对象,将应用程序组合在一起并创建一个“沙盒”来限制进程能做什么。
一个StartRestrictedProcess的例子
void StartRestrictedProcess() {// Check if we are not already associated with a job.// If this is the case ,there is no way to switch to// another job.BOOL bInJob = FALSE;IsProcessInJob(GetCurrentProcess(), NULL, &bInJob);if (bInJob) {MessageBox(NULL, TEXT("Process already in a job"),TEXT(""), MB_ICONINFORMATION | MB_OK);return;}// Create a job kernel object.HANDLE hjob = CreateJobObject(NULL,TEXT("Wintellect_RestrictedProcessJob"));// Place some restrictions on process in the job.// First, set some basic restrictions.JOBOBJECT_BASIC_LIMIT_INFORMATION jobli = { 0 };// The process always runs in the idle priority class.jobli.PriorityClass = IDLE_PRIORITY_CLASS;// The job cannot use more than 1 second of CPU time.jobli.PerJobUserTimeLimit.QuadPart = 10000; // 1sec in 100-ns intervals// These are the only 2 restrictions I want placed on the job (process.jobli.LimitFlags = JOB_OBJECT_LIMIT_PRIORITY_CLASS| JOB_OBJECT_LIMIT_JOB_TIME;SetInformationJobObject(hjob, JobObjectBasicLimitInformation, &jobli,sizeof(jobli));// Second, set some UI restrictions.JOBOBJECT_BASIC_UI_RESTRICTIONS jobuir;jobuir.UIRestrictionsClass = JOB_OBJECT_UILIMIT_NONE; // A fancy zero// The process can't log off the system.jobuir.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_EXITWINDOWS;// The process can't access USER objects(such as other windows)// in the system.jobuir.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;SetInformationJobObject(hjob, JobObjectBasicUIRestrictions, &jobuir,sizeof(jobuir));// Spawn the process that is to be in the job.// Note: you must first spawn the process and then place the process in// the job. This means that the process' thread must be initially// suspended so that it can't execute any code outside of the job's// restrictions.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);// Place the process in the job.// Note: if this process spawns any children, the children are// automatically part of the same job.AssignProcessToJobObject(hjob, pi.hProcess);// Now we can allow the child process' thread to execute code.ResumeThread(pi.hThread);CloseHandle(pi.hThread);// Wait for the process to terminate or// for all the job's allocated CPU time to be used.HANDLE h[2];h[0] = pi.hProcess;h[1] = hjob;DWORD dw = WaitForMultipleObjects(2, h, FALSE, INFINITE);switch (dw - WAIT_OBJECT_0) {case 0:// The process has terminated...break;case 1:// All of the job's allocated CPU time was used...break;}FILETIME CreationTime;FILETIME ExitTime;FILETIME KernelTime;FILETIME UserTime;TCHAR szInfo[MAX_PATH];GetProcessTimes(pi.hProcess, &CreationTime, &ExitTime,&KernelTime, &UserTime)