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 只有在下列為 true 時,才會將組碼和 affinity 遮罩變更為 *Affinity 中指定的值:

  • 組號有效。
  • affinity mask 是有效的 (也就是說,只會設定對應至群組中邏輯處理器的遮罩位) 。
  • 至少有一個在同質遮罩中指定的處理器為作用中。
如果不符合上述任一條件,線程的群組編號和親和性遮罩會保持不變。 如果 PreviousAffinity 不是 NULL,則例程會將零寫入 **PreviousAffinity* 中的組號和親和性遮罩。

此外,如果先前的群組親和性指派給使用者模式中的線程, KeSetSystemGroupAffinityThread 會將零寫入群組編號和上一個群組親和 遮罩。 為了回應群組編號和親和性遮罩都是零 的GROUP_AFFINITY 結構, KeRevertToUserGroupAffinityThread 會還原目前的使用者模式線程親和性。 如果使用者模式線程親和性在 KeSetSystemGroupAffinityThreadKeRevertToUserGroupAffinityThread 呼叫之間變更,則會將最新的使用者模式親和性指派給線程。 (應用程式可以呼叫 SetThreadGroupAffinity 之類的函式來變更 thread.) 的使用者模式群組親和性

在 *Affinity 中的新親和性遮罩生效之前, KeSetSystemGroupAffinityThread 會移除 (設定為零) 對應至目前未使用之處理器的任何同質遮罩位。 在後續 的 KeSetSystemGroupAffinityThread 呼叫中,例程寫入 *PreviousAffinity 的值可能包含以這種方式修改的同質遮罩。

相關的例程 KeSetSystemAffinityThreadEx 會變更呼叫線程的親和性遮罩,但此例程與 KeSetSystemGroupAffinityThread 不同,不接受組號做為輸入參數。 從 Windows 7 開始, KeSetSystemAffinityThreadEx 會假設 affinity mask 是指群組 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 開始提供。
目標平台 Universal
標頭 wdm.h (包括 Wdm.h、Wdm.h、Ntifs.h)
程式庫 NtosKrnl.lib
Dll NtosKrnl.exe
IRQL <= DISPATCH_LEVEL (请参阅一节) 。
DDI 合規性規則 HwStorPortProhibitedDIS (storport) PowerIrpDDis (wdm)

另請參閱

GROUP_AFFINITY

KeRevertToUserGroupAffinityThread

KeSetSystemAffinityThreadEx

PsSetSystemMultipleGroupAffinityThread