Функция 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 , только если верно следующее:
- Допустимый номер группы.
- Допустимая маска сходства (то есть задаются только биты маски, соответствующие логическим процессорам в группе).
- Активен по крайней мере один из процессоров, указанных в маске сходства.
Кроме того, 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) |