KeSetSystemGroupAffinityThread-Funktion (wdm.h)

Die KeSetSystemGroupAffinityThread-Routine ändert die Gruppennummer und die Affinitätsmaske des aufrufenden Threads.

Syntax

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

Parameter

[in] Affinity

Ein Zeiger auf eine GROUP_AFFINITY-Struktur , die die neue Gruppennummer und die gruppenrelative Affinitätsmaske für den aufrufenden Thread angibt.

[out, optional] PreviousAffinity

Ein Zeiger auf eine vom Aufrufer zugewiesene GROUP_AFFINITY Struktur, in die die Routine Informationen zur vorherigen Gruppenaffinität des aufrufenden Threads schreibt. Der Aufrufer kann diesen Zeiger später als Eingabeparameter für die KeRevertToUserGroupAffinityThread-Routine verwenden, um die vorherige Threadaffinität wiederherzustellen. Häufig schreibt KeSetSystemGroupAffinityThread Werte in diese Struktur, die keine gültigen Gruppenaffinitäten sind, aber eine besondere Bedeutung für KeRevertToUserGroupAffinityThread haben. Geben Sie in nachfolgenden KeSetSystemGroupAffinityThread-Aufrufen keine Zeiger auf diese speziellen Werte als Affinitätsparameter an.

Bei Bedarf kann der Aufrufer die Threadaffinität mehrmals ändern, indem KeSetSystemGroupAffinityThread mehrmals aufgerufen wird. Während des ersten dieser Aufrufe sollte der Aufrufer einen Wert ungleich NULL für PreviousAffinity angeben, damit die ursprüngliche Threadaffinität erfasst und später wiederhergestellt werden kann. Die späteren Aufrufe von KeSetSystemGroupAffinityThread können jedoch als Option PreviousAffinity = NULL festlegen. Weitere Informationen finden Sie in den Hinweisen.

Rückgabewert

Keine

Bemerkungen

Diese Routine ändert die Gruppennummer und die gruppenrelative Affinitätsmaske des aufrufenden Threads. Der Affinity-Parameter verweist auf eine GROUP_AFFINITY-Struktur . Die Gruppennummer und die Affinitätsmaske in dieser Struktur identifizieren eine Gruppe von Prozessoren, auf denen der Thread ausgeführt werden kann. Bei erfolgreicher Ausführung plant die Routine die Ausführung des Threads auf einem Prozessor in diesem Satz.

Wenn der PreviousAffinity-Parameter nicht NULL ist, speichert die Routine Informationen zur vorherigen Gruppenaffinität, die zu Beginn des Aufrufs in kraft waren, in der GROUP_AFFINITY Struktur, auf die PreviousAffinity verweist. Um die vorherige Threadaffinität wiederherzustellen, kann der Aufrufer den Zeiger auf diese Struktur als Eingabeparameter für die KeRevertToUserGroupAffinityThread-Routine bereitstellen.

In einem Multiprozessorsystem muss eine Kernelmodustreiberroutine, die im Kontext eines Benutzermodusthreads ausgeführt wird, möglicherweise KeSetSystemGroupAffinityThread aufrufen, um die Gruppenaffinität des Threads vorübergehend zu ändern. Bevor die Routine beendet wird, sollte keRevertToUserGroupAffinityThread aufgerufen werden, um die Affinitätsmaske des Threads auf den ursprünglichen Wert wiederherzustellen.

Ein Prozess kann eine Affinität für mehrere Gruppen gleichzeitig aufweisen. Ein Thread kann jedoch jederzeit nur einer Gruppe zugewiesen werden. Diese Gruppe befindet sich immer in der Affinität des Threadprozesses. Ein Thread kann die Gruppe ändern, der er zugewiesen ist, indem KeSetSystemGroupAffinityThread aufgerufen wird.

KeSetSystemGroupAffinityThread ändert die Gruppennummer und die Affinitätsmaske nur dann in die Werte, die in *Affinity angegeben sind, wenn Folgendes zutrifft:

  • Die Gruppennummer ist gültig.
  • Die Affinitätsmaske ist gültig (d. a. es werden nur Maskenbits festgelegt, die logischen Prozessoren in der Gruppe entsprechen).
  • Mindestens einer der Prozessoren, der in der Affinitätsmaske angegeben ist, ist aktiv.
Wenn eine dieser Bedingungen nicht erfüllt ist, bleiben die Gruppennummer und die Affinitätsmaske des Threads unverändert. Wenn PreviousAffinity ungleich NULL ist, schreibt die Routine null in die Gruppennummer und die Affinitätsmaske in **PreviousAffinity*.

Darüber hinaus schreibt KeSetSystemGroupAffinityThread null in die Gruppennummer und die Affinitätsmaske in *PreviousAffinity , wenn die vorherige Gruppenaffinität dem Thread im Benutzermodus zugewiesen wurde. Als Reaktion auf eine GROUP_AFFINITY-Struktur , in der die Gruppennummer und die Affinitätsmaske 0 (null) sind, stellt KeRevertToUserGroupAffinityThread die aktuelle Benutzermodusthreadaffinität wieder her. Wenn sich die Affinität des Benutzermodusthreads zwischen den Aufrufen KeSetSystemGroupAffinityThread und KeRevertToUserGroupAffinityThread ändert, wird dem Thread die neueste Benutzermodusaffinität zugewiesen. (Eine Anwendung kann eine Funktion wie SetThreadGroupAffinity aufrufen, um die Benutzermodusgruppenaffinität eines Threads zu ändern.)

Bevor die neue Affinitätsmaske in *Affinity wirksam wird, entfernt KeSetSystemGroupAffinityThread alle Affinitätsmaskenbits(null), die Prozessoren entsprechen, die derzeit nicht aktiv sind. In einem nachfolgenden KeSetSystemGroupAffinityThread-Aufruf kann der Wert, den die Routine in *PreviousAffinity schreibt, eine Affinitätsmaske enthalten, die auf diese Weise geändert wurde.

Eine verwandte Routine, KeSetSystemAffinityThreadEx, ändert die Affinitätsmaske des aufrufenden Threads, aber diese Routine akzeptiert im Gegensatz zu KeSetSystemGroupAffinityThread keine Gruppennummer als Eingabeparameter. Ab Windows 7 geht KeSetSystemAffinityThreadEx davon aus, dass sich die Affinitätsmaske auf Prozessoren in Gruppe 0 bezieht, die mit dem Verhalten dieser Routine in früheren Versionen von Windows kompatibel ist, die keine Gruppen unterstützen. Dieses Verhalten stellt sicher, dass vorhandene Treiber, die KeSetSystemAffinityThreadEx aufrufen und keine gruppenorientierten Features verwenden, in Multiprozessorsystemen mit mindestens zwei Gruppen ordnungsgemäß ausgeführt werden. Treiber, die gruppenorientierte Features in Windows 7 und höheren Versionen des Windows-Betriebssystems verwenden, sollten jedoch KeSetSystemGroupAffinityThread anstelle von KeSetSystemAffinityThreadEx aufrufen.

KeSetSystemGroupAffinityThread und KeRevertToUserGroupAffinityThread unterstützen eine Vielzahl von Aufrufmustern. Zwei Beispiele sind in den folgenden Diagrammen dargestellt.

Das folgende Diagramm stellt einen Treiberthread dar, der KeSetSystemGroupAffinityThread dreimal aufruft , um die Threadaffinität zu ändern, und dann KeRevertToUserGroupAffinityThread aufruft , um die ursprüngliche Threadaffinität wiederherzustellen.

Diagramm zur Veranschaulichung mehrerer Aufrufe zum Festlegen der Affinität.

Im vorherigen Diagramm sind die drei Felder mit der Bezeichnung "Affinität festlegen" Aufrufe von KeSetSystemGroupAffinityThread, und das Feld mit der Bezeichnung "Affinität rückgängig machen" ist ein Aufruf von KeRevertToUserGroupAffinityThread. Der erste KeSetSystemGroupAffinityThread-Aufruf verwendet den PreviousAffinity-Ausgabezeiger , um die ursprüngliche Threadaffinität zu speichern. In den nächsten beiden Aufrufen von KeSetSystemGroupAffinityThread (gekennzeichnet mit Sternchen) legt der Aufrufer PreviousAffinity auf NULL fest. Bevor der Thread beendet wird, ruft er KeRevertToUserGroupAffinityThread auf, um die Threadaffinität wiederherzustellen, die beim ersten KeSetSystemGroupAffinityThread-Aufruf gespeichert wurde.

Das folgende Diagramm zeigt ein etwas anderes Aufrufmuster, in dem KeSetSystemGroupAffinityThread - und KeRevertToUserGroupAffinityThread-Aufrufe geschachtelt sind. In diesem Diagramm verwendet jeder Aufruf von KeSetSystemGroupAffinityThread im Treiberthread den Ausgabeparameter PreviousAffinity , um die vorherige Threadaffinität zu speichern, und jeder dieser Aufrufe wird mit einem Aufruf von KeRevertToUserGroupAffinityThread gekoppelt, der die gespeicherte Threadaffinität wiederherstellt.

Diagramm zur Veranschaulichung geschachtelter Aufrufe zum Festlegen und Wiederherstellen der Affinität.

Im vorherigen Diagramm ruft Funktion A im Treiberthread zweimal Funktion B auf. Angenommen, der Thread hat beim Eintritt in Funktion A weiterhin die Affinität, die ihm von der Benutzermodusanwendung zugewiesen wurde. Daher speichert der KeSetSystemGroupAffinityThread-Aufruf in Funktion A die ursprüngliche Threadaffinität im Benutzermodus. Während des ersten Aufrufs von Funktion B speichert KeSetSystemGroupAffinityThread die vom Treiber in Funktion A zugewiesene Threadaffinität, und der entsprechende Aufruf von KeRevertToUserGroupAffinityThread stellt diese Affinität wieder her. Nach der Rückgabe von B stellt keRevertToUserGroupAffinityThread in A die ursprüngliche Benutzermodus-Threadaffinity-Affinität wieder her. Während des zweiten Aufrufs von B speichert der KeSetSystemGroupAffinityThread-Aufruf die ursprüngliche Threadaffinität im Benutzermodus, und der entsprechende Aufruf von KeRevertToUserGroupAffinityThread stellt diese Affinität wieder her. In diesem Beispiel muss Funktion B nicht wissen, ob der Aufrufer (Funktion A) die Threadaffinität vor dem Aufruf von B in einen vom Treiber definierten Wert geändert hat.

Wenn KeSetSystemGroupAffinityThread unter IRQL <= APC_LEVEL aufgerufen wird und der Aufruf erfolgreich ist, wird die neue Gruppenaffinität sofort wirksam. Wenn der Aufruf zurückgegeben wird, wird der aufrufende Thread bereits auf einem Prozessor ausgeführt, der in der neuen Gruppenaffinität angegeben ist. Wenn KeSetSystemGroupAffinityThread unter IRQL = DISPATCH_LEVEL aufgerufen wird und der Aufruf erfolgreich ist, wird die ausstehende Prozessoränderung zurückgestellt, bis der Aufrufer die IRQL unter DISPATCH_LEVEL senkt.

Ab Windows 11 und Windows Server 2022 umfassen Prozess- und Threadaffinitäten auf einem System mit mehr als 64 Prozessoren standardmäßig alle Prozessoren im System, und zwar über alle Prozessorgruppen hinweg. Um die Systemgruppenaffinität eines Threads auf mehrere Prozessorgruppen festzulegen, verwenden Sie PsSetSystemMultipleGroupAffinityThread.

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client) Verfügbar ab Windows 7.
Zielplattform Universell
Header wdm.h (include Wdm.h, Wdm.h, Ntifs.h)
Bibliothek NtosKrnl.lib
DLL NtosKrnl.exe
IRQL <= DISPATCH_LEVEL (siehe Abschnitt "Hinweise").
DDI-Complianceregeln HwStorPortProhibitedDIs(storport), PowerIrpDDis(wdm)

Weitere Informationen

GROUP_AFFINITY

KeRevertToUserGroupAffinityThread

KeSetSystemAffinityThreadEx

PsSetSystemMultipleGroupAffinityThread