设计一个服务器时,必须把一组进程当作一个单独的组来处理。例如,一个客户端也许会请求服务器执行一个应用程序并将结果返回给客户端。
由于许多客户端都可能连接到此服务器,所以服务器应该以某种方式限制客户端能请求的东西,避免任何一个客户端独占其所有资源,所以服务器应该以某种方式限制客户端能请求的东西,避免任何一个客户端独占其所有资源。这些限制包括可以分配给客户端请求的最大CPU时间,最小工作集和最大工作集大小,禁止客户端应用程序关闭计算机以及安全机制。
Windows提供了一个作业内核对象,它允许我们将进程组合在一起并创建一个“沙箱”来限制进程能够做什么。
检查当前进程是否与一个作业关联
BOOL IsProcessInJob(
HANDLE hProcess,
HANDLE hJob,
PBOOL pbInJob);
创建一个新的作业内核对象
HANDLE CreateJobObject(
PSECURITY_ATTRIBUTES psa,
PCTSTR pszName);
进程访问作业
HANDLE OpenJobObject(
DWORD dwDesireAccess,
BOOL bInheritHandle,
PCTSTR pszName);
不再访问作业对象,必须调用CloseHandle来关闭它的句柄,会导致所有进程不能访问该作业
对作业执行一些操作来建立一个沙箱,可以对作业应用以下几种限制
防止作业中的进程独占系统资源
防止作业内的进程更改用户界面
防止作业内的进程访问安全资源
SetInformationJobObject
SetInformationJobObject(
HANDLE hJob,
JOBOBJECTINFOCLASS JobObjectInformationClass,
PVOID pJobObjectInformation,
DWORD cdJobObjectInformationSize);
第一个参数指定要限制的作业。
第二个参数是一个枚举类型,指定了要施加的限制的类型。
第三个参数是一个数据结构的地址,数据结构中包含了具体的限制设置
第四个参数指出此数据结构的大小
限制类型 | 第二个参数的值 | 第三个参数对应的数据结构 |
基本限额 | JobObjectBasicLimitInformation | JOBOBJECT_BASIC_LIMIT_INFORMATION |
扩展后的基本限额 | JobObjectExtendedLimitInformation | JOBOBJECT_EXTENDED_LIMIT_INFORMATION |
基本的UI限制 | JobObjectBasicUIRestrictions | JOBOBJECT_BASIC_UI_RESTRICTIONS |
安全限额 | JobObjectSecurityLimitInformation | JOBOBJECT_SECURITY_LIMIT_INFORMATION |
其中JOBOBJECT_BASIC_LIMIT_INFORMATION结构为
typedef struct _JOBOBJECT_BASIC_LIMIT_INFORMATION{
LARGE_INTEGER PerProcessUserTimeLimit; //分配给每个进程的最大用户模式时间
LARGE_INTEGER PerJobUserTimeLimit; //限制分配给作业对象的最大用户模式时间
DWORD LimitFlags; //指定哪些限制应用于作业
DWORD MinimumWorkingSetSize; //指定每个进程的最大工作集和最小工作集
DWORD MaximumWorkingSetSize;
DWORD ActiveProcessLimit; //指定作业中能并发运行的进程的最大数量
DWORD_PTR Affinity; //指定能够运行进程的CPU的子集
DWORD PriorityClass; //指定关联所有进程的优先级类
DWORD SchedulingClass; //为作业中的线程指定一个相对时间量差
}JOBOBJECT_BASIC_LIMIT_INFORMATION,*PJOBOBJECT_BASIC_LIMIT_INFORMATION;
JOBOBJECET_EXTENDED_LIMIT_INFORMATION的结构为
typedef ?_JOBOBJECT_EXTENDED_LIMIT_INFORMATION{
JOBOBJECTION_BASIC_LIMIT_INFORMATION BasicLimitInformation;
IO_COUNTERS IoInfo;
SIZE_T ProcessMemoryLimit;
SIZE_T JobMemoryLIMIT;
SIZE_T PeakProcessMemoryUsed;
SIZE_T PeakJobMemoryUsed;
}JOBOBJECT_EXTENDED_LIMIT_INFORMATION,*JOBOBJECT_EXTENDED_LIMIT_INFORMATION;
用CreateProcess来生成打算放到作业中的进程
创建子进程且在允许它允许之前,必须调用以下函数
BOOL AssignProcessToJobObject(
HANDLE hJob,
HANDLE hProcess);
一旦进程已经属于作业的一部分,就不能再移动到另一个作业中,也不能称为所谓的“无业的“。
使用API
BOOL TerminateJobObject(
HANDLE hJob,
UINT uExitCode);