Как повысить приоритет ввода / вывода процесса? - PullRequest
13 голосов
/ 19 ноября 2008

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

Ответы [ 5 ]

21 голосов
/ 19 ноября 2008

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

Обратите внимание на две важные вещи:

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

Полезные 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.

14 голосов
/ 17 июня 2010

Похоже, что "реальный" способ установить приоритет ввода / вывода процесса - использовать 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, который устанавливает приоритет на очень низкий.

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

4 голосов
/ 27 марта 2011

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

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

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

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

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

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

2 голосов
/ 03 мая 2013

Обязательно правильно выровняйте структуру 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();
2 голосов
/ 17 марта 2011

Просто обновление для этого - все это можно сделать через .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, и он работает нормально. Не нужно устанавливать приоритет потока.

РЕДАКТИРОВАТЬ: это выше относится к приоритету ЦП процесса, а не к приоритету ввода / вывода, однако может быть некоторая корреляция / связь между приоритетом ЦП процесса и его приоритетом ввода / вывода.

...