作业可以对作业中的进程进行一系列的限制

来源:互联网 发布:淘宝推广方式钻石展位 编辑:程序博客网 时间:2024/04/30 09:24
具体用到的函数主要有下列: 

HANDLE   CreateJobObject( 
    LPSECURITY_ATTRIBUTES   lpJobAttributes,     //   SD 
    LPCTSTR   lpName                                                     //   job   name   
); 

BOOL   AssignProcessToJobObject( 
    HANDLE   hJob,           //   handle   to   job 
    HANDLE   hProcess     //   handle   to   process 
); 


BOOL   SetInformationJobObject( 
    HANDLE   hJob,                                                       //   handle   to   job 
    JOBOBJECTINFOCLASS   JobObjectInfoClass,   //   information   class 
    LPVOID   lpJobObjectInfo,                                 //   limit   information 
    DWORD   cbJobObjectInfoLength                         //   size   of   limit   information 

); 

SetInformationJobObject的第二个参数传递JobObjectBasicLimitInformation, 
第三个参数lpJobObjectInfo的类型可以是下面这个结构 

typedef   struct   _JOBOBJECT_BASIC_LIMIT_INFORMATION   { 
        LARGE_INTEGER   PerProcessUserTimeLimit; 
        LARGE_INTEGER   PerJobUserTimeLimit; 
        DWORD   LimitFlags; 
        SIZE_T   MinimumWorkingSetSize; 
        SIZE_T   MaximumWorkingSetSize; 
        DWORD   ActiveProcessLimit; 
        ULONG_PTR   Affinity; 
        DWORD   PriorityClass; 
        DWORD   SchedulingClass; 
}   JOBOBJECT_BASIC_LIMIT_INFORMATION,   *PJOBOBJECT_BASIC_LIMIT_INFORMATION; 

·PerProcessUserTimeLimit 限制一个线程在用户模式下的执行时间,系统周期性地对每一个作业中的进程进行检查,如果一个进程累计的执行时间超过了限制,进程将被终止。  


·PerJobUserTimeLimit 限制一个作业对象在用户模式下的执行时间,如果作业对象中所有进程在用户模式下执行的时间超过限制,则所有的进程都被终止,并且此时其它的进程也不能被关联到这个作业对象中,除非重新设置限制。  


对于JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION这个标志位,《Windows核心编程》是在JOBOBJECT_BASIC_LIMIT_INFORMATION这个结构里讲的,一开始简单的为JOBOBJECT_BASIC_LIMIT_INFORMATION的结构调用SetInformationJobObject,也没有判断该函数的返回值,结果死活不能让预想的程序顺利运行。后来在MSDN中看到这样一句对JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION标志的解释(This limit requires use of a JOBOBJECT_EXTENDED_LIMIT_INFORMATION structure. Its BasicLimitInformation member is a JOBOBJECT_BASIC_LIMIT_INFORMATION structure.)呵呵,很是郁闷,要使用JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION那么必须使用JOBOBJECT_EXTENDED_LIMIT_INFORMATION结构,简要代码如下:

 

 

HANDLE hJob = CreateJobObject(NULL, L"Ben");

 

         JOBOBJECT_BASIC_LIMIT_INFORMATION jobli = {0};

         jobli.PerJobUserTimeLimit.QuadPart = 10000000;

         jobli.LimitFlags = JOB_OBJECT_LIMIT_JOB_TIME|JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION;

       

         JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {0};

         jeli.BasicLimitInformation = jobli;

 

         SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli))

 

         CString cmdLine(L"D://DesignProgram//TestWin32Console//Debug//4.exe");

 

         STARTUPINFO si = { sizeof(si) };

         //si.wShowWindow = SW_HIDE;

         PROCESS_INFORMATION pi;

         CreateProcess(NULL, cmdLine.AllocSysString(), NULL, NULL, FALSE, CREATE_SUSPENDED,

                   NULL, NULL, &si, &pi);

 

         AssignProcessToJobObject(hJob, pi.hProcess);

         ResumeThread(pi.hThread);


关于JOB_OBJECT_LIMIT_JOB_TIME

2008-09-18 09:15 118人阅读 评论(0) 收藏 举报
 

1.  一个Console程序,执行1000×1000×1000次加法运算D:/DesignProgram/TestWin32Console/Debug/1.exe

2.  一个Console程序,是一个死循环,什么也不做D:/DesignProgram/TestWin32Console/Debug/2.exe

3.  一个Console程序,要求用户输入一个整数D:/DesignProgram/TestWin32Console/Debug/3.exe

现对以上3个程序执行进行如下测试:

         HANDLE hJob = CreateJobObject(NULL, L"Ben");

 

         JOBOBJECT_BASIC_LIMIT_INFORMATION jobli = {0};

         jobli.PerJobUserTimeLimit.QuadPart = 10000000;

         jobli.LimitFlags = JOB_OBJECT_LIMIT_JOB_TIME;

 

         ::SetInformationJobObject(hJob, JobObjectBasicLimitInformation, &jobli, sizeof(jobli));

 

         //CString cmdLine(L"D://DesignProgram//TestWin32Console//Debug//1.exe");

         //CString cmdLine(L"D://DesignProgram//TestWin32Console//Debug//2.exe");

         CString cmdLine(L"D://DesignProgram//TestWin32Console//Debug//3.exe");

 

         STARTUPINFO si = { sizeof(si) };

         PROCESS_INFORMATION pi;

         CreateProcess(NULL, cmdLine.AllocSysString(), NULL, NULL, FALSE, CREATE_SUSPENDED,

                   NULL, NULL, &si, &pi);

 

         AssignProcessToJobObject(hJob, pi.hProcess);

         ResumeThread(pi.hThread);

 

         CloseHandle(hJob);

         CloseHandle(pi.hProcess);

 

结果是12在消耗了1S 时间后正常结束,而3却没有结束。

原来在看《Windows核心编程》一书第5章时,书上在讲解作业这个概念时引用了一个例子程序类似上面的,但是却是去Create了一个CMD进程,自己执行时发现程序是永远不能自己结束的,不解。

自己测试了下,理解为:像CMD或者一个等待输入事件是一个I/O事件,操作系统在进程等待一个I/O事件时将进程挂起,所以根本不耗CPU时间,自然就到不了1S 的时间限定。


原创粉丝点击