【问题标题】:Set IO priority low without affecting thread priority设置 IO 优先级低而不影响线程优先级
【发布时间】:2014-10-27 15:32:25
【问题描述】:

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

我只知道我们可以设置:

SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);

但使用该 API,线程的优先级也很低。

【问题讨论】:

    标签: windows io thread-priority


    【解决方案1】:

    大约一年前我玩过这个,但是 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();
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-26
        • 2011-06-25
        • 1970-01-01
        • 1970-01-01
        • 2011-04-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多