将IO优先级设置为低而不影响线程优先级

时间:2014-09-03 07:56:05

标签: windows io thread-priority

是否有可以在不更改线程优先级的情况下将IO优先级设置为低的Windows API?

我只知道我们可以设置:

SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);

但是使用该API,线程也具有低优先级。

2 个答案:

答案 0 :(得分:0)

可能不是。我找不到方法,我明白为什么不可取。

如果线程直接与用户交互,则线程应具有正常优先级;如果线程在后台执行非紧急任务,则优先级较低。您描述的那种线程会导致用户在等待磁盘I / O时由于其低优先级而看到“此应用程序没有响应”警告。

答案 1 :(得分:0)

大约一年前,我曾玩弄过这个,但是I / O优先级与线程优先级不同,因为它后面没有繁重的调度,所以即使您说的低,即使没有其他I / 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();