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 调用中提供指向这些特殊值的指针作为 地关联 参数。
如有必要,调用方可以通过多次调用 KeSetSystemGroupAffinityThread 多次更改线程相关性。 在这些调用的第一个过程中,调用方应为 PreviousAffinity 指定非NULL 值,以便捕获原始线程相关性,然后还原。 但是,稍后调用 KeSetSystemGroupAffinityThread 可以根据需要设置 PreviousAffinity = NULL。 有关详细信息,请参阅“备注”。
返回值
没有
言论
此例程更改调用线程的组号和组相对相关性掩码。 地缘 参数指向 GROUP_AFFINITY 结构。 此结构中的组号和关联掩码标识线程可以运行一组处理器。 如果成功,该例程会将线程计划在此集中的处理器上运行。
如果 PreviousAffinity 参数为非NULL,则例程将保存上一个组相关性的信息(在调用开始时生效),PreviousAffinity 指向的 GROUP_AFFINITY 结构中。 若要还原以前的线程相关性,调用方可以将指向此结构的指针作为输入参数提供给 KeRevertToUserGroupAffinityThread 例程。
在多处理器系统中,在用户模式线程上下文中运行的内核模式驱动程序例程可能需要调用 KeSetSystemGroupAffinityThread 以暂时更改线程的组相关性。 在例程退出之前,它应调用 KeRevertToUserGroupAffinityThread,将线程的关联掩码还原到其原始值。
一个进程一次可以具有多个组的相关性。 但是,线程随时只能分配给一个组。 该组始终位于线程进程的关联中。 线程可以通过调用 KeSetSystemGroupAffinityThread来更改为其分配的组。
KeSetSystemGroupAffinityThread 将组号和地缘掩码更改为 *Affinity 中指定的值,前提是以下内容为 true:
- 组号有效。
- 关联掩码有效(即,仅设置与组中逻辑处理器对应的掩码位)。
- 在关联掩码中指定的至少一个处理器处于活动状态。
此外,KeSetSystemGroupAffinityThread 在 *PreviousAffinity 中将组号和地缘掩码写入零,前提是上一个组相关性在用户模式下分配给线程。 为了响应组号和地缘掩码均为零的 GROUP_AFFINITY 结构,KeRevertToUserGroupAffinityThread 还原当前用户模式线程相关性。 如果用户模式线程相关性在 KeSetSystemGroupAffinityThread 和 KeRevertToUserGroupAffinityThread 调用之间发生更改,则会将最新的用户模式相关性分配给该线程。 (应用程序可以调用 SetThreadGroupAffinity 等函数来更改线程的用户模式组相关性。
在 *Affinity 中的新关联掩码生效之前,KeSetSystemGroupAffinityThread 删除与当前未处于活动状态的处理器相对应的任何关联掩码位(设置为零)。 在后续的 KeSetSystemGroupAffinityThread 调用中,例程写入 *PreviousAffinity 的值可能包含以这种方式修改的关联掩码。
相关的例程,KeSetSystemAffinityThreadEx,更改调用线程的关联掩码,但此例程不同于 KeSetSystemGroupAffinityThread,不接受组号作为输入参数。 从 Windows 7 开始,KeSetSystemAffinityThreadEx 假设关联掩码是指组 0 中的处理器,这与早期版本的 Windows 中不支持组的此例程的行为兼容。 此行为可确保调用 KeSetSystemAffinityThreadEx 的现有驱动程序,并且不会在具有两个或更多组的多处理器系统中正确运行面向组的功能。 但是,在 Windows 7 及更高版本中使用任何面向组的功能的驱动程序应调用 KeSetSystemGroupAffinityThread,而不是 KeSetSystemAffinityThreadEx。
KeSetSystemGroupAffinityThread 和 KeRevertToUserGroupAffinityThread 支持各种调用模式。 下图显示了两个示例。
下图表示一个驱动程序线程,该线程调用 KeSetSystemGroupAffinityThread 三次来更改线程相关性,然后调用 KeRevertToUserGroupAffinityThread 以还原原始线程相关性。
在上图中,标记为“设置相关性”的三个框是调用 KeSetSystemGroupAffinityThread,标记为“还原相关性”的框是调用 KeRevertToUserGroupAffinityThread。 第一个 KeSetSystemGroupAffinityThread 调用使用 PreviousAffinity 输出指针来保存原始线程相关性。 在接下来的两次调用中,KeSetSystemGroupAffinityThread(标有星号),调用方将 PreviousAffinity 设置为 NULL。 在线程退出之前,它会调用 KeRevertToUserGroupAffinityThread 来还原由第一 KeSetSystemGroupAffinityThread 调用保存的线程相关性。
下图显示了一种有点不同的调用模式,其中嵌套了 KeSetSystemGroupAffinityThread 和 KeRevertToUserGroupAffinityThread 调用。 在此关系图中,驱动程序线程中对 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,并且调用成功,则挂起的处理器更改将延迟,直到调用方降低低于 DISPATCH_LEVEL 的 IRQL。
从 Windows 11 和 Windows Server 2022 开始,在具有 64 个以上的处理器、进程和线程相关性的系统上,默认情况下,所有 处理器组跨系统中的所有处理器。 若要在多个处理器组上设置线程的系统组相关性,请使用 PsSetSystemMultipleGroupAffinityThread。
要求
要求 | 价值 |
---|---|
最低支持的客户端 | 从 Windows 7 开始可用。 |
目标平台 | 普遍 |
标头 | wdm.h (包括 Wdm.h、Wdm.h、Ntifs.h) |
库 | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <= DISPATCH_LEVEL (请参阅“备注”部分)。 |
DDI 符合性规则 | HwStorPortProhibitedDIS(storport),PowerIrpDDis(wdm) |