【问题标题】:Preventing application from taking resources from other applications防止应用程序从其他应用程序获取资源
【发布时间】:2014-02-03 00:53:26
【问题描述】:

我有一个应用程序执行大量 CPU 和 I/O 繁重的工作。在完成这项工作时,它不应干扰其他应用程序。

例如,如果另一个应用程序正在充分利用我的应用程序正在读取的磁盘,我希望我的应用程序将其磁盘访问限制在非常低的速度,以免干扰其他应用程序。 CPU也是如此。例如,如果另一个应用程序正在编码视频,我不想从中窃取很多周期。

我尝试将我的线程置于后台模式,但我发现这些线程不会使用未使用的资源。在没有其他应用程序运行且几乎没有 CPU 或磁盘使用的情况下,在普通优先级线程上需要 1 秒的操作在后台线程上最多需要 5 分钟。

winapi 是否提供任何帮助我解决此问题的方法?

下面是我的应用程序磁盘使用情况的图片,而后台线程尝试计算 800 MB 文件的 SHA1 哈希值。如您所见,它几乎没有使用我的磁盘。在正常优先级下,它维持 20 MB+ 的读取。

编辑:澄清一下,“后台线程”是指优先级设置为后台模式的线程,而不是 C# 后台线程。

SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);

【问题讨论】:

    标签: c windows winapi throttling


    【解决方案1】:

    您的代码很好——THREAD_MODE_BACKGROUND_BEGIN 是您向系统发出该线程是后台线程并且其 I/O 将被视为low-priority 的信号。您可以使用SetPriorityClassPROCESS_MODE_BACKGROUND_BEGIN 在整个进程范围内实现相同的效果。您甚至可以使用SetFileInformationByHandleFileIoPriorityHintInfo 控制文件句柄粒度。

    所以你已经在做你打算做的事情了。但是你发现你的任务没有得到任何资源。这只能意味着至少有一个其他线程正在运行,并且比后台优先级更高,它正在使用资源。

    【讨论】:

    • 我确实有其他线程在做事,但我的磁盘利用率很低,我在 24 个处理器的机器上有 12 个线程。我的后台线程无法利用剩余资源对我来说没有意义。总体而言,Process Explorer 显示所有内容的利用率
    • 我认为有另一个线程正在使用磁盘,而后台线程永远不会看到。
    • 另一个线程可能正在使用磁盘,但吞吐量非常低(即 5 kb / 秒)。这仍然会阻止我的后台线程使用剩余的带宽吗?
    • 没想到
    • 我添加了截图;也许你能看到我看不到的东西。
    【解决方案2】:

    对于 CPU 利用率限制:

    只是不要使用 THREAD_MODE_BACKGROUND_BEGIN,任何低于正常值(具有负优先级提升)的东西都应该没问题。 Windows 会安排优先级较高的线程首先运行。如果您希望即使是动态优先级提升也几乎总是不足以干扰正常的优先级线程,请选择 THREAD_PRIORITY_IDLE。

    有关 IO 优先级的信息,click here

    【讨论】:

    • 我很好奇 - 为什么不使用THREAD_MODE_BACKGROUND_BEGIN?如果使用它会发生什么?根据我的实验,PROCESS_MODE_BACKGROUND_BEGIN 有时非常不合适,但THREAD_MODE_BACKGROUND_BEGIN 看起来完全没问题。有关我的发现的更多信息,请参阅:stackoverflow.com/a/30509372/193017
    猜你喜欢
    • 2014-06-19
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多