如何提高流程的I / O优先级?

时间:2008-11-19 08:15:02

标签: .net file-io windows-vista

我想提高进程的I / O优先级。 .NET和Windows Vista的答案都不错。 processexplorer也可以。

6 个答案:

答案 0 :(得分:21)

与通常的MS文档相比,相关信息似乎有点分散。这篇白皮书讨论了I/O Prioritization in windows。这个文档似乎都有测试标志,但我猜它可能大部分非常准确。

需要注意的两件重要事项:

  1. 您只能将IO请求的优先级降低到正常范围以上。
  2. 无论如何,驱动程序可以忽略任何此类请求并将其视为正常。
  3. 客户端应用程序的有用API是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类似:

    // 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 );
    

    对于.Net,使用P / Invoke做常见的事情。

答案 1 :(得分:14)

设置进程的IO优先级的“真实”方式似乎是使用NtSetInformationProcessProcessIoPriority信息类。不幸的是,这个API没有文档记录,但您可以通过将调试器附加到taskeng.exe并打破ExeTask::GetYourPrioritiesStraight来查看它。

我相信PROCESS_INFORMATION_CLASS的{​​{1}}值为33(0x21),优先级值如下:

ProcessIoPriority

根据我从调试器中可以看出的内容,上面的值是最佳猜测;任务调度程序似乎对优先级为7的任务使用值1,对优先级为5的任务使用值2(有关任务调度程序优先级的更多信息,请参阅this questionthis MSDN article)。使用Very Low: 0 Low: 1 Normal: 2 High: 3 or above? 呼叫SetPriorityClass时使用值0。

遗憾的是,我没有找到任何可用于此的公共API,除了@ 1800 INFORMATION的答案中的PROCESS_MODE_BACKGROUND_BEGIN方法,它将优先级设置为非常低。

编辑:我编写了一个实用程序,可用于查询或设置进程的IO优先级available here

答案 2 :(得分:4)

执行此操作的正确方法是使用 PROCESS_BACKGROUND_MODE_BEGIN 调用 SetProcessPriorityClass 以启动后台模式。这会导致极低(后台)I / O优先级和空闲CPU优先级。完成后,再次调用SetProcessPriorityClass,提供 PROCESS_BACKGROUND_MODE_END 。可以通过 SetThreadPriority 和THREAD_BACKGROUND_MODE_BEGIN / END在线程级别完成相同的工作。

如果要直接设置I / O优先级(与CPU优先级无关),则必须使用NT本机API。我记录了它here,但没有包含代码示例,因为我们都知道它们会被逐字翻录。

您需要的API是NT Native API NtSetInformationProcess 。使用此API可以更改I / O优先级。此API接受一个“类”变量,告诉它您要更改的进程的类型信息,该类变量必须设置为ProcessIoPriority。然后,您可以这种方式设置整个进程的I / O优先级。

同样,可以通过 NtQueryInformationProcess 检索I / O优先级。

坏消息是优先级有限。严重保留用于系统分页操作。这会让您感到正常非常低(背景)。在较新版本的Windows中可能会或可能不会实现低和高。至少似乎有部分支持。

如果您没有使用NT Native API的经验,首先要做的就是理解它们。完成后,您会发现它就像单个API调用一样简单。

答案 3 :(得分:2)

只是对此进行更新 - 它可以通过.NET完成而无需借助WinAPI ...

// Set the current process to run at 'High' Priority
System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
process.PriorityClass = System.Diagnostics.ProcessPriorityClass.High;

// Set the current thread to run at 'Highest' Priority
Thread thread = System.Threading.Thread.CurrentThread;
thread.Priority = ThreadPriority.Highest;

我已经尝试过在WPF应用程序中设置进程优先级,并且工作正常。不需要设置线程优先级。

编辑:上面的内容与进程的CPU优先级有关,而不是I / O优先级,但进程的CPU优先级与其I / O优先级之间可能存在一些关联/连接。

答案 4 :(得分:2)

调用FILE_IO_PRIORITY_HINT_INFO时,请务必正确对齐SetFileInformationByHandle结构。

否则,您将获得ERROR_NOACCESS(错误998,0x000003E6)。

_declspec(align(8)) FILE_IO_PRIORITY_HINT_INFO priorityHint;
priorityHint.PriorityHint = IoPriorityHintLow;

BOOL ret = SetFileInformationByHandle(hFile, FileIoPriorityHintInfo, &priorityHint, sizeof(FILE_IO_PRIORITY_HINT_INFO));
DWORD err = GetLastError();

答案 5 :(得分:0)

如果您希望应用程序正在处理的文件具有关键的I / O优先级,我相信将文件重命名为.mp3将会为您带来帮助! Windows会对.mp3,.mp4等媒体文件执行此操作 可以通过“磁盘”选项卡中的Process Hacker观察到这一点,只要读取mp3,您就会发现它们全都在关键的I / O中。我没有找到任何有关此文档,可能是注册表设置?

编辑:这是在Win 7上,我只是在Win 10上尝试过,所以不一样,我看到它曾经一次处于高优先级,但通常是正常的,但是从不严格。在撰写本文时,我尝试了Win 7 VM,但它也没有做到这一点!我不知道为什么我的主要Win 7会不会怀疑是否有第三方,但是呢?有人知道吗?