I want to increase the I/O priority of a process. Answers for both .NET and Windows Vista would be nice. processexplorer is ok as well.
Using this API you can change the I/O priority. This API accepts a 'class' variable telling it what type of information about the process you want to change, that class variable must be set to ProcessIoPriority. You can then set the entire process's I/O priority in this manner.
You can change the scheduling priority of a running process to a value lower or higher than the base scheduling priority by using the renice command from the command line. This command changes the nice value of a process.
I/O priority queueing is used to control deferred I/O requests. If this function is invoked, all deferred I/O requests, except paging and swapping, will be queued according to the I/O priorities associated with the requesting address spaces. Paging and swapping are always handled at the highest priority.
If the nice value of a process is lower, it gets a higher priority, which means the CPU will execute that process more often. But, if the nice value of a process is higher, it will be assigned a lower priority, which means that the CPU will execute that process less often (whenever it gets an opportunity).
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With