How can I/O priority of a process be increased?
The relevant information seems to be a bit scattered compared to the usual MS documentation. There is this white paper that discusses I/O Prioritization in windows. This doc seems to have beta flags all over it but I guess it's probably mostly pretty accurate.
Two important things to note:
- You can only reduce the priority of IO requests below normal.
- The driver can ignore any such request and treat it as normal anyway.
The useful APIs for client applications are 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 which is similar:
// 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 );
For .Net do the usual stuff with P/Invoke.
It looks like the "real" way to set the IO priority of a process is using NtSetInformationProcess
with the ProcessIoPriority
information class. Unfortunately this API is undocumented, but you can see it in action by attaching a debugger to taskeng.exe and breaking in ExeTask::GetYourPrioritiesStraight
.
I believe the PROCESS_INFORMATION_CLASS
value for ProcessIoPriority
is 33 (0x21), and the priority values are as follows:
Very Low: 0
Low: 1
Normal: 2
High: 3 or above?
The values above are a best-guess based on what I can tell from the debugger; the task scheduler seems to use a value of 1 for tasks with priority 7, and a value of 2 for tasks with priority 5 (see this question and this MSDN article for more on task scheduler priorities). Calling SetPriorityClass
with PROCESS_MODE_BACKGROUND_BEGIN
uses a value of 0.
I have unfortunately not found any public API that can be used for this, other than the SetPriorityClass
method in @1800 INFORMATION's answer, which sets the priority to Very Low.
Edit: I've written a utility that can be used to query or set the IO prority of a process, available here.