嵌套作业
应用程序可以使用嵌套作业来管理进程的子集。 嵌套作业还允许使用作业来托管其他也使用作业的应用程序。
Windows 7、Windows Server 2008 R2、Windows XP sp3、Windows Server 2008、Windows Vista 和 Windows Server 2003: 进程只能与单个作业相关联。 嵌套作业是在 Windows 8 和 Windows Server 2012 中引入的。
本主题概述了嵌套作业的作业嵌套和行为:
有关作业和作业对象的常规信息,请参阅 作业对象。
嵌套作业层次结构
嵌套作业具有父子关系,其中每个子作业在其父作业中包含进程的子集。 如果作业中已有的进程已添加到另一个作业,则默认情况下,如果系统可以形成有效的作业层次结构,并且两个作业都不能设置 UI 限制(SetInformationJobObjectJobObjectBasicUIRestrictions)。
图 1 显示了一个作业层次结构,其中包含标记为 P0 到 P7 的进程树。 作业 1 是作业 2 和作业 4 父作业,它是作业 3 的 祖先。 作业 2 是作业 3 的 直接父级;作业 3 是作业 2 的直接子 。 作业 1、2 和 3 构成 作业链 其中作业 1 和 2 是作业 3 父作业链。 作业链中的结束作业是该作业中进程的 即时作业。 在图 1 中,作业 3 是进程 P2、P3 和 P4 的直接作业。
的嵌套作业层次结构
嵌套作业还可用于管理对等进程的组。 在图 2 中显示的作业层次结构中,作业 1 是作业 2 的父作业。 请注意,作业层次结构可能仅包含进程树的一部分。 在图 2 中,P0 不在层次结构中,但其子进程 P1 到 P5 是。
创建嵌套作业层次结构
作业层次结构中的进程是使用 AssignProcessToJobObject 函数显式关联到作业对象,或在进程创建过程中隐式关联,与独立作业相同。 创建作业和分配进程的顺序决定了是否可以创建层次结构。
若要使用显式关联生成作业层次结构,必须使用 createJobObject创建所有作业对象,然后 AssignProcessToJobObject 必须多次调用每个进程才能将进程与其所属的每个作业相关联。 若要确保作业层次结构有效,请先将所有进程分配到层次结构根目录中的作业,然后将进程子集分配给即时子作业对象,依此等。 如果按此顺序将进程分配给作业,则子作业在其父作业中始终有一部分进程,而层次结构是在创建层次结构时进行嵌套所必需的。 如果进程按随机顺序分配给作业,则在某些时候,子作业将具有不在其父作业中的进程。 嵌套不允许这样做,它将导致 AssignProcessToJobObject 失败。
当进程在创建过程中隐式关联到作业时,子进程与其父进程的作业链中的每个作业相关联。 如果即时作业对象允许分离,则子进程会从直接作业对象和父作业链中的每个作业中断,向上移动层次结构,直到到达不允许分离的作业。 如果即时作业对象不允许分离,则即使其父作业链中的作业允许它,子进程也不会中断。
嵌套作业的作业限制和通知
对于某些资源限制,父作业链中为作业设置的限制决定了为子作业强制实施的 有效限制。 子作业的有效限制可能比父作业的限制更严格,但限制性不能降低。 例如,如果子作业的优先级类ABOVE_NORMAL_PRIORITY_CLASS并且其父作业的优先级类NORMAL_PRIORITY_CLASS,则子作业中的进程的有效限制NORMAL_PRIORITY_CLASS。 但是,如果子作业的优先级类BELOW_NORMAL_PRIORITY_CLASS,则子作业中的进程的有效限制BELOW_NORMAL_PRIORITY_CLASS。 对优先级类、相关性、提交费用、每个进程执行时间限制、计划类限制以及工作集最小值和最大值强制实施有效限制。 有关特定资源限制的详细信息,请参阅 SetInformationJobObject。
发生某些事件(如新进程创建或资源限制冲突)时,会将消息发送到与作业关联的 I/O 完成端口。 当超出某些限制时,作业还可以注册以接收通知。 对于非嵌套作业,消息将发送到与作业关联的 I/O 完成端口。 对于嵌套作业,该消息将发送到与触发消息的作业的父作业链中的任何作业关联的每个 I/O 完成端口。 子作业不需要有关联的 I/O 完成端口,才能将触发的消息发送到作业链中较高父作业的 I/O 完成端口。 有关特定消息的详细信息,请参阅 JOBOBJECT_ASSOCIATE_COMPLETION_PORT。
嵌套作业的资源会计
嵌套作业的资源会计信息描述了与该作业关联的每个进程的用法,包括子作业中的进程。 因此,作业链中的每个作业都表示其自己的进程使用的聚合资源,以及作业链中每个子作业的进程。
嵌套作业的终止
当作业层次结构中的作业终止时,系统会终止该作业及其所有子作业中的进程,从层次结构底部的子作业开始。 每个终止进程使用的未完成资源将按父作业收费。
作业句柄必须具有JOB_OBJECT_TERMINATE访问权限,与独立作业的访问权限相同。