第5章:作业
1. 为了把一组进程当做一个单独的组来处理,windows提供了一个作业(job)内核对象,它允许我们将进程组合在一起并创建一个”沙箱“来限制进程能够做什么。最好把作业对象想象成一个进程容器。理解:从这里我们要注意关键,作业是管理进程集合的容器,所谓管理主要就是对进程行为加以限制!
2. 如果进程已与一个作业关联,就无法将当前进程或者它的任何子进程从作业中去除,这个安全特性可以确保进程无法摆脱对它施加的限制。
3. 检测某进程是否与一个作业已经关联,使用IsProcessInJob函数。
4. 使用CreateJobObject 函数创建作业。
5. 使用SetInformationJobObject 函数对作业中的进程施加限制。限制类型请参考http://msdn.microsoft.com/en-us/library/windows/desktop/ms686216(v=vs.85).aspx,对作业加以限制的内容是本章的重点内容,类型有十种之多,而且对应的结构以及对进程的影响各异。
6. 使用AssignProcessToJobObject 函数把进程放入作业中,如果想在创建进程的同时用作业来管理此进程,应该在创建进程的时候使用CREATE_SUPENDED标志,加入作业列表后再启动进程。一旦进程已经属于作业的一部分,它就不能再移动到另一个作业中,也不能成为所谓”无业的“。当作业中的一个进程生成了另一个进程的时候,新进程将自动成为父进程所属于的作业的一部分(但可以通过CreateProcess 创建子进程时使用特殊参数使子进程摆脱控制)。
7. 使用TerminateJobObject 函数来终止作业中的所有进程,它是通过对每个进程调用TerminateProcess 来做到的,每个进程的终止后的内存清理留给系统自动完成。
8. 使用QueryInformationJobObject 函数来查询作业当前的限制。查询类型参数请参考http://msdn.microsoft.com/en-us/library/windows/desktop/ms684925(v=vs.85).aspx。除了查询限制,还可以查询作业的统计信息。注意这里的类型参数与SetInformationJobObject类型参数不完全相同。每个结构都值得深入研究,这里这个接口写的方便性以及文档的说明质量实在不可恭维。
9. 作业通知通过使用完成端口来实现。创建完成端口后,通过SetInformationJobObject 带JobObjectAssociateCompletionPortInformation 参数和完成端口句柄绑定作业。这样,系统将监视作业,只要有事件发生,就会把它们投递到I/O完成端口,我们调用GetQueuedCompletionStatus来监视完成端口(一般是另开线程做监视动作,使用QueryInformationJobObject来获取完成键和完成端口句柄)。
10. 对作业完成端口的事件处理是用户需要关心的事情。
11. 对于JeffreyRichter 的光盘代码的理解,我在05-JobLab程序中,发现使用创建作业的那个进程创建的CMD窗口明明已经关联到作业成功,但不能通过QueryInformationJobObject查找到其进程信息,已经发了信到微软,但愿得到解答。
对于随书的代码内容,很多地方都有。但我也上传我使用的那一份吧:http://download.csdn.net/detail/eagleatustb/4690967