《Windows核心编程》第五章——作业

#include <windows.h>
#include<iostream>
#include <tchar.h>
using namespace std;

typedef struct ThreadParam{
    HANDLE hIOCP;
    DWORD dwNumBytesTransferred;
    ULONG CompletionKey;
    LPOVERLAPPED pOverlapped;
    DWORD dwTimeOut;
}*pThreadParam;

void MonitorCompletePort(LPVOID lpParam){
    pThreadParam tp = (pThreadParam)lpParam;
    BOOL bRuslt = FALSE;
    printf("Run thread success.
");
    while (TRUE){
        bRuslt = GetQueuedCompletionStatus(tp->hIOCP, &tp->dwNumBytesTransferred, &tp->CompletionKey, &tp->pOverlapped, INFINITE);
        switch (tp->dwNumBytesTransferred){
        case JOB_OBJECT_MSG_END_OF_JOB_TIME:
            printf("JOB_OBJECT_MSG_END_OF_JOB_TIME
");
            break;
        case JOB_OBJECT_MSG_END_OF_PROCESS_TIME:
            printf("JOB_OBJECT_MSG_END_OF_PROCESS_TIME
");
            break;
        case JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT:
            printf("JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT
");
            break;
        case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:
            printf("JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO
");
            break;
        case JOB_OBJECT_MSG_NEW_PROCESS:
            printf("JOB_OBJECT_MSG_NEW_PROCESS
");
            break;
        case JOB_OBJECT_MSG_EXIT_PROCESS:
            printf("JOB_OBJECT_MSG_EXIT_PROCESS
");
            break;
        case JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS:
            printf("JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS
");
            break;
        case JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT:
            printf("JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT
");
            break;
        case JOB_OBJECT_MSG_JOB_MEMORY_LIMIT:
            printf("JOB_OBJECT_MSG_JOB_MEMORY_LIMIT
");
            break;
        case JOB_OBJECT_MSG_NOTIFICATION_LIMIT:
            printf("JOB_OBJECT_MSG_NOTIFICATION_LIMIT
");
            break;
        }
    }
    printf("End thread success.
");
}

void main(){
    //Check if the process has been in a job. If not, create a job object.
    BOOL bInJob = FALSE;
    IsProcessInJob(GetCurrentProcess(), NULL, &bInJob);//如果用命令行启动,就返回false;如果直接用vs调试启动,就返回true。
   if (bInJob){ printf("Been in a job.
"); }
  HANDLE hJob
= CreateJobObject(NULL, _T("Wintellect_RestrictedProcessJob")); //Add some basic restrictions.
   JOBOBJECT_BASIC_LIMIT_INFORMATION jobli = { 0 };
   jobli.PriorityClass
= IDLE_PRIORITY_CLASS;
   jobli.PerJobUserTimeLimit.QuadPart
= 10000;
   jobli.LimitFlags
= JOB_OBJECT_LIMIT_PRIORITY_CLASS | JOB_OBJECT_LIMIT_JOB_TIME;
   SetInformationJobObject(hJob, JobObjectBasicLimitInformation,
&jobli, sizeof(jobli));
   JOBOBJECT_BASIC_UI_RESTRICTIONS jobuir;
   jobuir.UIRestrictionsClass
= JOB_OBJECT_UILIMIT_NONE;
   jobuir.UIRestrictionsClass
|= JOB_OBJECT_UILIMIT_EXITWINDOWS;
   jobuir.UIRestrictionsClass
|= JOB_OBJECT_UILIMIT_HANDLES;
  SetInformationJobObject(hJob, JobObjectBasicUIRestrictions,
&jobuir, sizeof(jobuir)); //Create a process object
STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi;
BOOL bResult
= CreateProcess("C:\Windows\System32\notepad.exe", NULL, NULL, NULL, FALSE, CREATE_SUSPENDED | CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
AssignProcessToJobObject(hJob, pi.hProcess);
//Create io completion port.
HANDLE hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 3);
JOBOBJECT_ASSOCIATE_COMPLETION_PORT joacp; joacp.CompletionKey
= (PVOID)1;
joacp.CompletionPort
= hIOCP;
SetInformationJobObject(hJob, JobObjectAssociateCompletionPortInformation,
&joacp, sizeof(joacp)); //Create a thread to monitor the job.
DWORD dwNumBytesTransferred = 0;
ULONG lCompletionKey
= 0;
ThreadParam tp;
OVERLAPPED op
= { 0 };
tp.hIOCP
= hIOCP;
tp.dwNumBytesTransferred
= dwNumBytesTransferred;
tp.CompletionKey
= lCompletionKey;
tp.pOverlapped
= NULL;
tp.dwTimeOut
= INFINITE;
DWORD lpThread;
HANDLE hThread
= CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MonitorCompletePort, &tp, 0, &lpThread); Sleep(5000);
ResumeThread(pi.hThread); CloseHandle(pi.hThread);
WaitForSingleObject(hThread, INFINITE);
//Naution:if use while(true) in the thread, the thread will never return. If use INIFINITE as param //of function WaitForSingleObject, the main thread will never return. CloseHandle(hThread); getchar(); }

第一次执行GetQueuedCompletionStatus返回6(JOB_OBJECT_MSG_NEW_PROCESS),表示将一个进程添加进一个作业;第二次执行GetQueuedCompletionStatus返回1(JOB_OBJECT_MSG_END_OF_JOB_TIME),表示作业超时;第二次执行GetQueuedCompletionStatus返回1(JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO),表示作业中进程的数量降至0.

原文地址:https://www.cnblogs.com/predator-wang/p/8689815.html