Поделиться через


Функция 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 несколько раз. Во время первого из этих вызовов вызывающий объект должен указать значение, отличное от NULL , для Параметра PreviousAffinity , чтобы можно было записать исходное сходство потоков, а затем восстановить. Однако последующие вызовы KeSetSystemGroupAffinityThread могут в качестве параметра задать Значение PreviousAffinity = NULL. Дополнительные сведения см. в подразделе "Примечания".

Возвращаемое значение

None

Remarks

Эта подпрограмма изменяет номер группы и маску сходства относительно группы вызывающего потока. Параметр Affinity указывает на структуру GROUP_AFFINITY . Номер группы и маска сходства в этой структуре определяют набор процессоров, на которых может выполняться поток. В случае успеха подпрограмма планирует выполнение потока на процессоре в этом наборе.

Если параметр PreviousAffinity не равен NULL, подпрограмма сохраняет сведения о предыдущем сходстве групп, которые действовали в начале вызова, в структуре GROUP_AFFINITY , на которую указывает PreviousAffinity . Чтобы восстановить предыдущее сходство потоков, вызывающий объект может предоставить указатель на эту структуру в качестве входного параметра для подпрограммы KeRevertToUserGroupAffinityThread .

В многопроцессорной системе подпрограмме драйвера в режиме ядра, которая выполняется в контексте потока пользовательского режима, может потребоваться вызвать KeSetSystemGroupAffinityThread , чтобы временно изменить сходство группы потока. Перед завершением процедуры она должна вызвать KeRevertToUserGroupAffinityThread , чтобы восстановить маску сходства потока до его исходного значения.

Процесс может иметь сходство для нескольких групп одновременно. Однако поток может быть назначен только одной группе в любое время. Эта группа всегда находится в сходстве процесса потока. Поток может изменить группу, которой он назначен, вызвав KeSetSystemGroupAffinityThread.

KeSetSystemGroupAffinityThread изменяет номер группы и маску сходства на значения, указанные в *Affinity , только если верно следующее:

  • Допустимый номер группы.
  • Допустимая маска сходства (то есть задаются только биты маски, соответствующие логическим процессорам в группе).
  • Активен по крайней мере один из процессоров, указанных в маске сходства.
Если какое-либо из этих условий не выполняется, номер группы и маска сходства потока остаются неизменными. Если параметр PreviousAffinity не равен NULL, подпрограмма записывает ноль в номер группы и маску сходства в **PreviousAffinity*.

Кроме того, KeSetSystemGroupAffinityThread записывает ноль как в номер группы, так и в маску сходства в *PreviousAffinity , если предыдущее сходство группы было назначено потоку в пользовательском режиме. В ответ на GROUP_AFFINITY структуру, в которой номер группы и маска сходства равны нулю, KeRevertToUserGroupAffinityThread восстанавливает текущее сходство потоков в пользовательском режиме. Если сопоставление потоков пользовательского режима изменяется между вызовами KeSetSystemGroupAffinityThread и KeRevertToUserGroupAffinityThread , последнее сходство пользовательского режима назначается потоку. (Приложение может вызывать функцию , например SetThreadGroupAffinity , чтобы изменить сходство групп в пользовательском режиме потока.)

Прежде чем новая маска сходства в *Affinity вступит в силу, KeSetSystemGroupAffinityThread удаляет (устанавливает в нулевое значение) все биты маски сходства, соответствующие процессорам, которые в настоящее время не активны. В последующем вызове KeSetSystemGroupAffinityThread значение, которое подпрограмма записывает в *PreviousAffinity , может содержать маску сходства, которая была изменена таким образом.

Связанная подпрограмма KeSetSystemAffinityThreadEx изменяет маску сходства вызывающего потока, но эта подпрограмма, в отличие от KeSetSystemGroupAffinityThread, не принимает номер группы в качестве входного параметра. Начиная с Windows 7, KeSetSystemAffinityThreadEx предполагает, что маска сходства относится к процессорам в группе 0, что совместимо с поведением этой подпрограммы в более ранних версиях Windows, которые не поддерживают группы. Это гарантирует, что существующие драйверы, вызывающие KeSetSystemAffinityThreadEx и не использующие функции, ориентированные на группу, будут правильно работать в многопроцессорных системах с двумя или более группами. Однако драйверы, использующие любые функции, ориентированные на группу в Windows 7 и более поздних версиях операционной системы Windows, должны вызывать KeSetSystemGroupAffinityThread вместо KeSetSystemAffinityThreadEx.

KeSetSystemGroupAffinityThread и KeRevertToUserGroupAffinityThread поддерживают различные шаблоны вызовов. На следующих схемах показаны два примера.

На следующей схеме представлен поток драйвера, который три раза вызывает KeSetSystemGroupAffinityThread для изменения сходства потоков, а затем вызывает KeRevertToUserGroupAffinityThread для восстановления исходного сходства потоков.

Схема, иллюстрирующая несколько вызовов для задания сходства.

На предыдущей схеме три поля с меткой "Установить сходство" являются вызовами KeSetSystemGroupAffinityThread, а поле с меткой "Восстановить сходство" является вызовом KeRevertToUserGroupAffinityThread. Первый вызов KeSetSystemGroupAffinityThread использует выходной указатель PreviousAffinity для сохранения исходного сходства потоков. В следующих двух вызовах KeSetSystemGroupAffinityThread (помеченных звездочками) вызывающий объект присваивает параметру PreviousAffinityзначение NULL. Перед выходом потока он вызывает KeRevertToUserGroupAffinityThread для восстановления сходства потока, сохраненного первым вызовом KeSetSystemGroupAffinityThread .

На следующей схеме показан несколько другой шаблон вызова, в котором вложены пары вызовов KeSetSystemGroupAffinityThread и KeRevertToUserGroupAffinityThread . На этой схеме каждый вызов KeSetSystemGroupAffinityThread в потоке драйвера использует выходной параметр PreviousAffinity для сохранения предыдущего сходства потоков, и каждый из этих вызовов сопряжен с вызовом KeRevertToUserGroupAffinityThread , который восстанавливает сохраненное сходство потоков.

Схема, иллюстрирующая вложенные вызовы для задания и восстановления сходства.

На предыдущей схеме функция A в потоке драйвера дважды вызывает функцию B. Предположим, что при входе в функцию A поток по-прежнему имеет сходство, назначенное ему приложением пользовательского режима. Таким образом, вызов KeSetSystemGroupAffinityThread в функции A сохраняет исходное сходство потоков в пользовательском режиме. Во время первого вызова функции B KeSetSystemGroupAffinityThread сохраняет сходство потоков, назначенное драйвером в функции A, а соответствующий вызов KeRevertToUserGroupAffinityThread восстанавливает это сходство. После возврата B функция KeRevertToUserGroupAffinityThread в A восстанавливает исходное сходство потоков в пользовательском режиме. Во время второго вызова B вызов KeSetSystemGroupAffinityThread сохраняет исходное сходство потоков в пользовательском режиме, а соответствующий вызов KeRevertToUserGroupAffinityThread восстанавливает это сходство. Суть этого примера в том, что функции B не нужно знать, изменил ли вызывающий объект (функцию A) сходство потоков на определенное драйвером значение перед вызовом B.

Если keSetSystemGroupAffinityThread вызывается по адресу IRQL <= APC_LEVEL и вызов выполнен успешно, то новое сходство группы вступает в силу немедленно. Когда вызов возвращается, вызывающий поток уже выполняется на процессоре, указанном в новом сходстве группы. Если keSetSystemGroupAffinityThread вызывается по адресу IRQL = DISPATCH_LEVEL и вызов выполняется успешно, ожидающее изменение процессора откладывается до тех пор, пока вызывающий объект не понизит значение IRQL ниже DISPATCH_LEVEL.

Начиная с 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)

См. также раздел

GROUP_AFFINITY

KeRevertToUserGroupAffinityThread

KeSetSystemAffinityThreadEx

PsSetSystemMultipleGroupAffinityThread