作业对象

作业对象 允许将进程组作为一个单元进行管理。 作业对象是可南交、安全、可共享的对象,用于控制与其关联的进程的属性。 对作业对象执行的作会影响与作业对象关联的所有进程。 示例包括强制实施限制,例如工作集大小和进程优先级或终止与作业关联的所有进程。

创建作业

若要创建作业对象,请使用 CreateJobObject 函数。 创建作业时,不会与该作业关联任何进程。

若要将进程与作业相关联,请使用 AssignProcessToJobObject 函数。 在进程与作业关联后,无法断开关联。 进程可以与嵌套作业层次结构中的多个作业相关联。 有关详细信息,请参阅 嵌套作业

Windows 7、Windows Server 2008 R2、SP3、Windows Server 2008、Windows Vista 和 Windows Server 2003 的 Windows XP: 进程只能与一个作业相关联。 作业不能嵌套。 在 Windows 8 和 Windows Server 2012 中添加了嵌套作业的功能。

调用 CreateJobObject 函数时,可以为作业对象指定安全描述符。 有关详细信息,请参阅 作业对象安全和访问权限

在作业中管理进程

进程与作业关联后,默认情况下,它使用 createProcess 创建的任何子进程也与该作业相关联。 (使用 Win32_Process.Create 创建的子进程与作业无关。可以通过设置作业的扩展限制JOB_OBJECT_LIMIT_BREAKAWAY_OK或JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK来更改此默认行为。

  • 如果作业具有扩展限制JOB_OBJECT_LIMIT_BREAKAWAY_OK并且父进程是使用CREATE_BREAKAWAY_FROM_JOB标志创建的,则父进程的子进程与作业无关。
  • 如果作业具有扩展限制JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK,则与作业关联的任何父进程的子进程不与作业关联。 不需要使用CREATE_BREAKAWAY_FROM_JOB标志创建父进程。

如果作业是嵌套的,则层次结构中父作业的分离设置会影响子进程是否与层次结构中的另一个作业相关联。 有关详细信息,请参阅 嵌套作业

若要确定某个进程是否在作业中运行,请使用 IsProcessInJob 函数。

若要终止当前与作业对象关联的所有进程,请使用 TerminateJobObject 函数。

作业限制和通知

作业可以对与作业关联的每个进程强制实施工作集大小、进程优先级和作业结束时间限制等限制。 如果与作业关联的进程尝试从作业建立的限制中增加其工作集大小或进程优先级,函数调用会成功,但会以无提示方式忽略。 作业还可以设置在超出通知时触发通知的限制,但允许作业继续运行。

若要设置作业的限制,请使用 SetInformationJobObject 函数。 有关可为作业设置的可能限制的列表,请参阅以下主题:

必须为与作业对象关联的每个进程单独设置安全限制。 有关详细信息,请参阅 进程安全性和访问权限

具有 SP3 和 Windows Server 2003 的 Windows XP:SetInformationJobObject 函数可用于设置与作业对象关联的所有进程的安全限制。 从 Windows Vista 开始,必须为每个与作业对象关联的进程单独设置安全限制。

如果作业是嵌套的,则层次结构中的父作业会影响为作业强制执行的限制。 有关详细信息,请参阅 嵌套作业

如果作业具有关联的 I/O 完成端口,则当超出特定作业限制时,它可以接收通知。 当超出限制或发生某些其他事件时,系统将消息发送到完成端口。 若要将完成端口与作业相关联,请使用 SetInformationJobObject 函数与 job 对象信息类 JobObjectAssociateCompletionPortInformation 和指向 JOBOBJECT_ASSOCIATE_COMPLETION_PORT 结构的指针。 最好在作业处于非活动状态时执行此作,以减少在完成端口关联期间状态更改的进程缺少通知的可能性。

所有消息都直接从作业发送,就像作业调用了 PostQueuedCompletionStatus 函数一样。 线程必须使用 GetQueuedCompletionStatus 函数来监视完成端口以拾取消息。 请注意,除了 JobObjectNotificationLimitInformation 信息类设置的限制外,无法保证将消息传送到完成端口:消息到达失败并不一定意味着事件未发生。 JobObjectNotificationLimitInformation 设置的限制通知可以到达完成端口。 有关可能的消息列表,请参阅 JOBOBJECT_ASSOCIATE_COMPLETION_PORT

作业的资源会计

作业对象记录其所有关联进程的基本会计信息,包括已终止的进程。 若要检索此会计信息,请使用 QueryInformationJobObject 函数。 有关为作业维护的会计信息的列表,请参阅以下主题:

如果作业对象嵌套,则会在其父作业中聚合每个子作业的会计信息。 有关详细信息,请参阅 嵌套作业

管理作业对象

当作业对象的所有进程都终止时,作业对象的状态将设置为信号,因为指定的作业结束时间限制已超出。 使用 WaitForSingleObjectWaitForSingleObjectEx 监视此事件的作业对象。

若要获取现有作业对象的句柄,请使用 OpenJobObject 函数,并在创建对象时指定该对象的名称。 只能打开命名的作业对象。

若要关闭作业对象句柄,请使用 CloseHandle 函数。 作业在关闭其最后一个句柄并且所有关联的进程已终止时被销毁。 但是,如果作业指定了JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE标志,则关闭最后一个作业对象句柄将终止所有关联的进程,然后销毁作业对象本身。 如果嵌套作业指定了JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE标志,则关闭最后一个作业对象句柄将终止与作业及其层次结构中的子作业关联的所有进程。

管理使用作业对象的进程树

从 Windows 8 和 Windows Server 2012 开始,应用程序可以使用 嵌套作业 来管理使用多个作业对象的进程树。 但是,必须在 Windows 7、Windows Server 2008 R2 或不支持嵌套作业的早期版本的 Windows 上运行的应用程序必须以其他方式管理进程树。

如果工具必须管理使用作业对象的进程树,并且无法使用嵌套作业,则该工具和进程树的成员都必须合作。 使用以下选项之一:

  • 使用JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK限制。 如果该工具使用此限制,则无法监视整个进程树。 该工具只能监视它添加到作业的进程。 如果这些进程创建子进程,则它们不与作业关联。 在此选项中,子进程可以与其他作业对象相关联。

  • 使用JOB_OBJECT_LIMIT_BREAKAWAY_OK限制。 如果该工具使用此限制,则它可以监视整个进程树,除了树的任何成员显式脱离树的进程之外。 树的成员可以通过使用 CREATE_BREAKAWAY_FROM_JOB 标志调用 CreateProcess 函数,然后调用 AssignProcessToJobObject 函数,从而在新作业对象中创建子进程。 否则,成员必须处理 AssignProcessToJobObject 失败的情况。

    如果工具未监视树,则CREATE_BREAKAWAY_FROM_JOB标志不起作用。 因此,这是首选选项,但它需要事先了解正在监视的进程。

  • 通过设置JOB_OBJECT_LIMIT_BREAKAWAY_OK和JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK限制来防止任何类型的分离。 在此选项中,该工具可以监视整个进程树。 但是,如果子进程尝试通过调用 AssignProcessToJobObject将自身或其他子进程与作业关联,则调用将失败。 如果进程设计为与特定作业相关联,则此失败可能会阻止进程正常工作。