KeSetSystemGroupAffinityThread 函数 (wdm.h)

KeSetSystemGroupAffinityThread 例程更改调用线程的组号和关联掩码。

语法

void KeSetSystemGroupAffinityThread(
  [in]            PGROUP_AFFINITY Affinity,
  [out, optional] PGROUP_AFFINITY PreviousAffinity
);

参数

[in] Affinity

指向 GROUP_AFFINITY 结构的指针,该结构指定调用线程的新组号和组相对关联掩码。

[out, optional] PreviousAffinity

指向调用方分配 GROUP_AFFINITY 结构的指针,例程在其中写入有关调用线程上一组相关性的信息。 调用方稍后可以将此指针用作 KeRevertToUserGroupAffinityThread 例程的输入参数,以还原以前的线程相关性。 通常, KeSetSystemGroupAffinityThread 会将不是有效组相关性但对 KeRevertToUserGroupAffinityThread 具有特殊意义的值写入此结构。 在后续的 KeSetSystemGroupAffinityThread 调用中,不要提供指向这些特殊值的指针作为 Affinity 参数。

如有必要,调用方可以通过多次调用 KeSetSystemGroupAffinityThread 来多次更改线程相关性。 在第一次调用期间,调用方应为 PreviousAffinity 指定一个非 NULL 值,以便可以捕获原始线程相关性并在以后还原。 但是,以后对 KeSetSystemGroupAffinityThread 的 调用可以选择将 PreviousAffinity = 设置为 NULL。 有关详细信息,请参阅“备注”。

返回值

备注

此例程更改调用线程的组号和组相对关联掩码。 Affinity 参数指向GROUP_AFFINITY结构。 此结构中的组号和关联掩码标识线程可以在其上运行的一组处理器。 如果成功,例程会将线程计划为在此集中的处理器上运行。

如果 PreviousAffinity 参数为非 NULL,则例程会将有关上一个组相关性的信息(在调用开始时生效)保存在 PreviousAffinity 指向的GROUP_AFFINITY结构中。 若要还原以前的线程相关性,调用方可以提供指向此结构的指针作为 KeRevertToUserGroupAffinityThread 例程的输入参数。

在多处理器系统中,在用户模式线程的上下文中运行的内核模式驱动程序例程可能需要调用 KeSetSystemGroupAffinityThread 来临时更改线程的组相关性。 在例程退出之前,它应调用 KeRevertToUserGroupAffinityThread ,以将线程的关联掩码还原为其原始值。

一个进程一次可以具有多个组的相关性。 但是,一个线程在任何时候只能分配给一个组。 该组始终与线程的进程关联。 线程可以通过调用 KeSetSystemGroupAffinityThread 更改分配给它的组。

KeSetSystemGroupAffinityThread 仅当以下情况成立时,才会将组号和关联掩码更改为 “相关性 ” 中指定的值:

  • 组号有效。
  • 关联掩码是有效的 (也就是说,仅) 设置与组中逻辑处理器对应的掩码位。
  • 关联掩码中指定的至少一个处理器处于活动状态。
如果不满足这些条件中的任何一个,线程的组号和关联掩码保持不变。 如果 PreviousAffinity 为非 NULL,则例程会将零写入 **PreviousAffinity* 中的组号和关联掩码。

此外, KeSetSystemGroupAffinityThread 会将零写入 *PreviousAffinity 中的组号和关联掩码(如果以前的组相关性是在用户模式下分配给线程的)。 为了响应组号和关联掩码均为零 的GROUP_AFFINITY 结构, KeRevertToUserGroupAffinityThread 还原当前用户模式线程相关性。 如果 KeSetSystemGroupAffinityThreadKeRevertToUserGroupAffinityThread 调用之间的用户模式线程相关性发生更改,则会将最新的用户模式相关性分配给线程。 (应用程序可以调用 SetThreadGroupAffinity 等函数来更改 thread 的用户模式组相关性。)

在 *Affinity 中的新关联掩码生效之前, KeSetSystemGroupAffinityThread 将删除 (设置为零) 与当前未处于活动状态的处理器对应的任何关联掩码位。 在后续 的 KeSetSystemGroupAffinityThread 调用中,例程写入 *PreviousAffinity 的值可能包含以这种方式修改的关联掩码。

相关例程 KeSetSystemAffinityThreadEx 更改调用线程的关联掩码,但此例程与 KeSetSystemGroupAffinityThread 不同,不接受组号作为输入参数。 从 Windows 7 开始, KeSetSystemAffinityThreadEx 假定关联掩码引用组 0 中的处理器,这与不支持组的早期版本的 Windows 中此例程的行为兼容。 此行为可确保调用 KeSetSystemAffinityThreadEx 且不使用面向组的功能的现有驱动程序在具有两个或更多组的多处理器系统中正常运行。 但是,在 Windows 7 及更高版本的 Windows 操作系统中使用任何面向组的功能的驱动程序应调用 KeSetSystemGroupAffinityThread ,而不是 KeSetSystemAffinityThreadEx

KeSetSystemGroupAffinityThreadKeRevertToUserGroupAffinityThread 支持各种调用模式。 下图显示了两个示例。

下图显示了一个驱动程序线程,该线程调用 KeSetSystemGroupAffinityThread 三次以更改线程相关性,然后调用 KeRevertToUserGroupAffinityThread 以还原原始线程相关性。

说明多个调用以设置相关性的关系图。

在上图中,标记为“设置相关性”的三个框是对 KeSetSystemGroupAffinityThread 的调用,标记为“还原相关性”的框是对 KeRevertToUserGroupAffinityThread 的调用。 第一个 KeSetSystemGroupAffinityThread 调用使用 PreviousAffinity 输出指针来保存原始线程相关性。 在接下来的两次对 KeSetSystemGroupAffinityThread 的调用 (标有星号) 中,调用方将 PreviousAffinity 设置为 NULL。 在线程退出之前,它会调用 KeRevertToUserGroupAffinityThread 来还原由第一个 KeSetSystemGroupAffinityThread 调用保存的线程相关性。

下图显示了一个略有不同的调用模式,其中 嵌套了 KeSetSystemGroupAffinityThreadKeRevertToUserGroupAffinityThread 调用对。 在此图中,驱动程序线程中对 KeSetSystemGroupAffinityThread 的每次调用都使用 PreviousAffinity 输出参数来保存以前的线程相关性,并且其中每个调用都与对 KeRevertToUserGroupAffinityThread 的调用配对,以还原保存的线程相关性。

说明设置和还原相关性的嵌套调用的关系图。

在上图中,驱动程序线程中的函数 A 调用函数 B 两次。 假设在进入函数 A 时,线程仍具有用户模式应用程序分配给它的相关性。 因此,函数 A 中的 KeSetSystemGroupAffinityThread 调用会保存原始的用户模式线程相关性。 在第一次调用函数 B 期间, KeSetSystemGroupAffinityThread 将在函数 A 中保存驱动程序分配的线程相关性,而对 KeRevertToUserGroupAffinityThread 的相应调用将还原此相关性。 B 返回后,A 中的 KeRevertToUserGroupAffinityThread 将还原原始的用户模式线程相关性。 在第二次调用 B 期间, KeSetSystemGroupAffinityThread 调用会保存原始的用户模式线程相关性,而对 KeRevertToUserGroupAffinityThread 的相应调用将还原此相关性。 此示例的要点在于,函数 B 不需要知道调用方是否 (函数 A) 调用 B 之前将线程关联更改为驱动程序定义的值。

如果在 IRQL <= APC_LEVEL调用 KeSetSystemGroupAffinityThread 并且调用成功,则新的组相关性将立即生效。 当调用返回时,调用线程已在新组关联中指定的处理器上运行。 如果在 IRQL = DISPATCH_LEVEL调用 KeSetSystemGroupAffinityThread 并且调用成功,则挂起的处理器更改将推迟,直到调用方将 IRQL 降低到以下DISPATCH_LEVEL。

从 Windows 11 和 Windows Server 2022 开始,在处理器数超过 64 的系统上,默认情况下,进程和线程相关性跨所有处理器组跨系统中的所有处理器。 若要在多个处理器组上设置线程的系统组相关性,请使用 PsSetSystemMultipleGroupAffinityThread

要求

要求
最低受支持的客户端 从 Windows 7 开始可用。
目标平台 通用
标头 wdm.h (包括 Wdm.h、Wdm.h、Ntifs.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL <= DISPATCH_LEVEL (请参阅“备注”部分) 。
DDI 符合性规则 HwStorPortProhibitedDDI (storport) PowerIrpDDis (wdm)

另请参阅

GROUP_AFFINITY

KeRevertToUserGroupAffinityThread

KeSetSystemAffinityThreadEx

PsSetSystemMultipleGroupAffinityThread