【发布时间】:2014-10-27 15:32:25
【问题描述】:
是否有可以在不更改线程优先级的情况下将 IO 优先级设置为低的 Windows API?
我只知道我们可以设置:
SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);
但使用该 API,线程的优先级也很低。
【问题讨论】:
标签: windows io thread-priority
是否有可以在不更改线程优先级的情况下将 IO 优先级设置为低的 Windows API?
我只知道我们可以设置:
SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);
但使用该 API,线程的优先级也很低。
【问题讨论】:
标签: windows io thread-priority
大约一年前我玩过这个,但是 I/O 优先级不像线程优先级,因为它背后没有繁重的调度,所以如果你说低,即使没有其他 I/O,它也会是低速O 继续,对于可能以不良方式阻塞其他 I/O 的关键也是如此。 顺便说一句,我最终根本没有使用它,太慢了,或者严重阻塞了。
public static void lowerio()
{
int THREAD_SET_INFORMATION = 0x0020;
uint currid = (uint)GetCurrentThreadId();
IntPtr thrhandle = OpenThread(THREAD_SET_INFORMATION, false, currid);
int PRIO_HIGH = -5;
int PRIO_CRITICAL = -4;
if (thrhandle != IntPtr.Zero)
{
int iopriority = (int)IO_PRIORITY_HINT.IoPriorityLow;
int res = NtSetInformationThread(thrhandle, ThreadInformationClass.ThreadIoPriority, ref iopriority, Marshal.SizeOf(iopriority));
CloseHandle(thrhandle);
}
}
private enum IO_PRIORITY_HINT : int
{
IoPriorityVeryLow = 0, // Defragging, content indexing and other background I/Os.
IoPriorityLow, // Prefetching for applications.
IoPriorityNormal, // Normal I/Os.
IoPriorityHigh, // Used by filesystems for checkpoint I/O.
IoPriorityCritical, // Used by memory manager. Not available for applications.
MaxIoPriorityTypes
};
private enum ThreadInformationClass : int
{
ThreadBasicInformation, // q: THREAD_BASIC_INFORMATION
ThreadTimes, // q: KERNEL_USER_TIMES
ThreadPriority, // s: KPRIORITY
ThreadBasePriority, // s: LONG
ThreadAffinityMask, // s: KAFFINITY
ThreadImpersonationToken, // s: HANDLE
ThreadDescriptorTableEntry, // q: DESCRIPTOR_TABLE_ENTRY (or WOW64_DESCRIPTOR_TABLE_ENTRY)
ThreadEnableAlignmentFaultFixup, // s: BOOLEAN
ThreadEventPair,
ThreadQuerySetWin32StartAddress, // q: PVOID
ThreadZeroTlsCell, // 10
ThreadPerformanceCount, // q: LARGE_INTEGER
ThreadAmILastThread, // q: ULONG
ThreadIdealProcessor, // s: ULONG
ThreadPriorityBoost, // qs: ULONG
ThreadSetTlsArrayAddress,
ThreadIsIoPending, // q: ULONG
ThreadHideFromDebugger, // s: void
ThreadBreakOnTermination, // qs: ULONG
ThreadSwitchLegacyState,
ThreadIsTerminated, // q: ULONG // 20
ThreadLastSystemCall, // q: THREAD_LAST_SYSCALL_INFORMATION
ThreadIoPriority, // qs: IO_PRIORITY_HINT
ThreadCycleTime, // q: THREAD_CYCLE_TIME_INFORMATION
ThreadPagePriority, // q: ULONG
ThreadActualBasePriority,
ThreadTebInformation, // q: THREAD_TEB_INFORMATION (requires THREAD_GET_CONTEXT + THREAD_SET_CONTEXT)
ThreadCSwitchMon,
ThreadCSwitchPmu,
ThreadWow64Context, // q: WOW64_CONTEXT
ThreadGroupInformation, // q: GROUP_AFFINITY // 30
ThreadUmsInformation, // q: THREAD_UMS_INFORMATION
ThreadCounterProfiling,
ThreadIdealProcessorEx, // q: PROCESSOR_NUMBER
ThreadCpuAccountingInformation, // since WIN8
ThreadSuspendCount, // since WINBLUE
ThreadHeterogeneousCpuPolicy, // q: KHETERO_CPU_POLICY // since THRESHOLD
ThreadContainerId, // q: GUID
ThreadNameInformation, // qs: THREAD_NAME_INFORMATION
ThreadSelectedCpuSets,
ThreadSystemThreadInformation, // q: SYSTEM_THREAD_INFORMATION // 40
ThreadActualGroupAffinity, // since THRESHOLD2
ThreadDynamicCodePolicyInfo,
ThreadExplicitCaseSensitivity,
ThreadWorkOnBehalfTicket,
ThreadSubsystemInformation, // q: SUBSYSTEM_INFORMATION_TYPE // since REDSTONE2
ThreadDbgkWerReportActive,
ThreadAttachContainer,
ThreadManageWritesToExecutableMemory, // MANAGE_WRITES_TO_EXECUTABLE_MEMORY // since REDSTONE3
ThreadPowerThrottlingState, // THREAD_POWER_THROTTLING_STATE
MaxThreadInfoClass
};
[DllImport("ntdll.dll")]
private static extern int NtSetInformationThread(
[In] IntPtr threadHandle,
[In] ThreadInformationClass threadInformationClass,
[In] ref int threadInformation,
[In] int threadInformationLength
);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenThread(int dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
[DllImport("Kernel32", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
public static extern Int32 GetCurrentThreadId();
【讨论】:
可能不会。我找不到方法,但我明白为什么它是不可取的。
如果线程直接与用户交互,则它们应具有正常优先级,如果它们在后台执行非紧急任务,则应具有低优先级。您描述的线程类型会导致用户看到“此应用程序没有响应”警告,只要它由于其低优先级而等待磁盘 I/O。
【讨论】: