有时候我们需要将一组进程当作一个单体来处理,另外,也可能需要限制某个进程所能访问的资源。Windows提供了一个称为作业 (job)的内核对象,它允许我们将进程组在一起并创建一个“沙箱”来限制进行能够做些什么。 那么我们可以将作业理解成一个进程的容器。如果一个进程已经与一个作业关联,则该进程及它的所有子进程都无法从作业中去除掉,这个安全特性可以保证进程无法摆脱对它施加的限制。
创建作业内核对象函数:HANDLE CreateJobObject();
根据作业对象名字,另一进程通过“打开作业作业对象函数:HANDLE OpenJobObject()”对作业进行访问。
1. 对作业的进程施加限制
创建一个作业之后,一般会根据作业中的进程能够执行哪些操作来建立一个沙箱,可限制的类型:
1)基本限额和扩展基本限额,用于防止作业中的进程独占系统资源;
2)基本的UI限制,用于防止作业内的进得更改用户界面;
3)安全限额,用于防止作业内的进程访问安全资源(文件、注册表子项等)。
施加限制函数 :SetInformationJobObject()
2.将进程放入作业中
CreateProcess时,需指定CREATE_SUSPENDDE标志,然后调用AssignProcessToJobObject(),将进程放入到作业中。
3.终止作业中的所有进程
通过调用TerminateJobObject()可杀死作业内部所有进程,这类似于对作业内的每个进程调用TerminateProcess,将所有的退出码设为uExitCode.
4.作业通知
1)对于一些简单的通知,可通知类似WaitForSingleObject这样的函数来等待通知,比如想知道进程分配的CPU时间是否已用完,因为如果作业中的进得还没用完分配的CPU时间,作业内核对象就处于未触发状态。如果作业的所有进程都用完了所分配的CPU时间,Windows会强行杀死作业中的所有进程并触发作业内核对象。
2)对于一些更详细的通知,比如进程创建/终止运行,这些需创建一个I/O完成端口内核对象,并作业对象与完成端口关联,然后必须 有一个或多个线程等待作业通知到达完成端口,再进行处理。