Подтвердить что ты не робот

Как повысить приоритет I/O процесса?

Я хочу увеличить приоритет ввода-вывода процесса. Ответы для .NET и Windows Vista были бы приятными. processexplorer тоже в порядке.

4b9b3361

Ответ 1

Соответствующая информация, по-видимому, немного разбросана по сравнению с обычной MS-документацией. Существует эта статья, в которой обсуждается Приоритизация ввода/вывода в окнах. У этого документа, по-видимому, есть бета-флаги, но я думаю, что он, вероятно, в основном довольно точный.

Следует отметить две важные вещи:

  • Вы можете уменьшить приоритет запросов ввода-вывода ниже обычного.
  • Драйвер может игнорировать любой такой запрос и рассматривать его как обычно в любом случае.

Полезными API-интерфейсами для клиентских приложений являются SetFileInformationByHandle:

FILE_IO_PRIORITY_HINT_INFO priorityHint;
priorityHint.PriorityHint = IoPriorityHintLow;
result = SetFileInformationByHandle( hFile,
                                     FileIoPriorityHintInfo,
                                     &priorityHint,
                                     sizeof(PriorityHint));

SetPriorityClass:

// reduce CPU, page and IO priority for the whole process
result = SetPriorityClass( GetCurrentProcess(),
                           PROCESS_MODE_BACKGROUND_BEGIN);
// do stuff
result = SetPriorityClass( GetCurrentProcess(),
                           PROCESS_MODE_BACKGROUND_END);

SetThreadPriority, который похож:

// reduce CPU, page and IO priority for the current thread
SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);
// do stuff
SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END);

SetFileBandwithReservation:

// reserve bandwidth of 200 bytes/sec
result = SetFileBandwidthReservation( hFile,
                                  1000,
                                  200,
                                  FALSE,
                                  &transferSize,
                                  &outstandingRequests );

Для .Net сделайте обычный материал с помощью P/Invoke.

Ответ 2

Похоже, что "реальный" способ установить приоритет ввода-вывода процесса с помощью NtSetInformationProcess с информационным классом ProcessIoPriority. К сожалению, этот API недокументирован, но вы можете увидеть его в действии, добавив отладчик к taskeng.exe и взломав ExeTask::GetYourPrioritiesStraight.

Я считаю, что значение PROCESS_INFORMATION_CLASS для ProcessIoPriority равно 33 (0x21), а значения приоритета следующие:

Very Low: 0
Low: 1
Normal: 2
High: 3 or above?

Значения, приведенные выше, являются наилучшей предпосылкой, основанной на том, что я могу сказать от отладчика; планировщик задач, похоже, использует значение 1 для задач с приоритетом 7 и значение 2 для задач с приоритетом 5 (см. этот вопрос и эта статья MSDN для получения дополнительных сведений о приоритетах планировщика задач). Вызов SetPriorityClass с PROCESS_MODE_BACKGROUND_BEGIN использует значение 0.

Я, к сожалению, не нашел публичного API, который можно использовать для этого, кроме метода SetPriorityClass в ответе @1800 Information, который устанавливает приоритет Very Low.

Редактирование: я написал утилиту, которая может быть использована для запроса или установки IO prority процесса, доступного здесь.

Ответ 3

Правильный способ сделать это - вызвать SetProcessPriorityClass с помощью PROCESS_BACKGROUND_MODE_BEGIN, чтобы запустить фоновый режим. Это приводит к очень низкому (второстепенному) приоритету ввода-вывода и приоритету приоритета процессора. Когда все будет сделано, снова вызовите SetProcessPriorityClass, поставьте PROCESS_BACKGROUND_MODE_END. То же самое можно сделать на уровне потока через SetThreadPriority и THREAD_BACKGROUND_MODE_BEGIN/END.

Если вы хотите напрямую установить приоритет ввода-вывода, независимо от приоритета ЦП, вы должны использовать собственные API-интерфейсы NT. Я зарегистрировал его здесь, но не включил примеры кода, поскольку все мы знаем, что они разорваны дословно.

Необходимым API является NT Native API NtSetInformationProcess. Используя этот API, вы можете изменить приоритет ввода-вывода. Этот API принимает переменную класса, сообщающую, какой тип информации о процессе, который вы хотите изменить, для этой переменной класса должен быть установлен ProcessIoPriority. Таким образом вы можете установить весь приоритет ввода-вывода процесса.

Аналогично, приоритет ввода-вывода можно получить с помощью NtQueryInformationProcess.

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

Если у вас нет опыта работы с API-интерфейсами NT, первое, что нужно сделать, это понять их. Как только вы это сделаете, вы увидите, что это так же просто, как и один вызов API.

Ответ 4

Обязательно выравнивайте структуру FILE_IO_PRIORITY_HINT_INFO правильно при вызове SetFileInformationByHandle.

В противном случае вы получите ERROR_NOACCESS (ошибка 998, 0x000003E6).

_declspec(align(8)) FILE_IO_PRIORITY_HINT_INFO priorityHint;
priorityHint.PriorityHint = IoPriorityHintLow;

BOOL ret = SetFileInformationByHandle(hFile, FileIoPriorityHintInfo, &priorityHint, sizeof(FILE_IO_PRIORITY_HINT_INFO));
DWORD err = GetLastError();

Ответ 5

Просто обновление для этого - все это можно сделать через .NET, не прибегая к использованию WinAPI...

// Set the current process to run at 'High' Priority
System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
process.PriorityClass = System.Diagnostics.ProcessPriorityClass.High;

// Set the current thread to run at 'Highest' Priority
Thread thread = System.Threading.Thread.CurrentThread;
thread.Priority = ThreadPriority.Highest;

Я пробовал описанное выше, установив приоритет процесса в приложении WPF, и он отлично работает. Не нужно было устанавливать приоритет потока.

EDIT: это выше относится к приоритету процессора процесса, в отличие от приоритета ввода-вывода, однако может существовать некоторая корреляция/соединение между приоритетом процессора процессора и его приоритетом ввода-вывода.