【问题标题】:how to lower thread priority in C/C++如何降低 C/C++ 中的线程优先级
【发布时间】:2019-11-19 08:21:42
【问题描述】:

我想降低线程的优先级。

我的线程的默认策略是SCHED_OTHER,我的系统(Ubuntu)下的优先级范围是[0,0](我通过sched_get_priority_min(SCHED_OTHER)sched_get_priority_max(SCHED_OTHER)得到范围)这意味着所有线程SCHED_OTHER 将具有相同的优先级。

有没有办法降低SCHED_OTHER 的优先级?我已经搜索了一段时间,我找到了nice 值系统,但不确定这是否是正确的方法,因为man page 说好的值是针对进程而不是线程,我很困惑...

谁能给出正确的解决方案来做到这一点,也许用一个短代码sn-p?谢谢!

添加:

为什么要降低线程的优先级:

我有一个工作线程,它定期进行一些密集的计算(例如,每分钟几秒钟,因此会导致一些 CPU 使用高峰),我的整个系统将经历周期性的性能下降。但是这个工作线程的优先级很低,只要能在下一分钟之前完成计算就可以了。所以我想在这个时间窗口平滑地摊销这个任务的计算。

【问题讨论】:

  • pthread_setschedparam
  • 这听起来像an XY problem。对于什么问题,您决定降低线程优先级是解决方案吗?
  • 请注意,在 Linux(和大多数其他 Unix 操作系统)中,默认调度程序(又名 SCHED_OTHER)会在发现线程使用大量 CPU 周期时自动降低线程的优先级。因此,如果您担心 CPU 繁重的计算线程可能会阻止大部分空闲,例如需要低延迟的 GUI 线程,那么操作系统可能已经自动为您处理了该问题。
  • @JeremyFriesner 我已经更新了一些关于我的情况的描述,默认的系统调度可能无法处理我的问题,所以我想手动降低线程的优先级。根据我的情况有什么建议吗?
  • @AndrewHenle 感谢您的建议,我已经更新了我的问题以澄清我的情况,有什么建议吗?

标签: c++ c linux multithreading pthreads


【解决方案1】:

假设您运行的是最新版本的 Linux 内核,您可以尝试将线程设置为 SCHED_IDLE,如 this link 所示,即:

void set_idle_priority() {                                              
   struct sched_param param;
   param.sched_priority = 0;
   if (pthread_setschedparam(pthread_self(), SCHED_IDLE, &param) != 0)
      perror("pthread_setschedparam");
} 

在这种模式下,你的线程只会在系统中没有其他东西想要运行时运行。

...也就是说,我不确定这样做是否真的会解决您的问题,因为根据您的描述,您一开始就不应该遇到这个问题。特别是,以正常/默认优先级运行的占用 CPU 的线程的存在不会显着减慢您的系统,因为调度程序应该自动检测其占用 CPU 的性质并隐式降低它的优先级,而无需您采取任何特殊步骤。这让我认为您的问题可能不是线程的 CPU 使用率,而是其他问题,例如您的线程可能正在用完系统的所有可用 RAM 容量,导致系统不得不将内存分页到磁盘。这肯定会导致系统大大减慢。另一种可能性是,如果您的线程正在执行大量磁盘 I/O(尽管这似乎不太可能,因为在这种情况下,它可能不会固定 CPU 内核)。

您可以尝试用一个简单的 CPU 燃烧循环临时替换线程的计算,例如:

void my_thread_entry_func()
{
   while(1) {/* empty */}
}

...并运行它只是为了看看它是否也会引起减速。如果不是,那么导致减速的不是 CPU 使用本身,而是您的线程正在执行的其他操作,您需要进行进一步测试以准确缩小线程执行路径的哪些部分是罪魁祸首。

【讨论】:

  • 感谢您的解决方案!设置空闲部分缓解周期性性能降级,我认为这是我的问题的一个潜在解决方案,因为我只是希望该线程不会周期性地使 CPU 突发,而是平滑地摊销其计算,因此它不会占用其他工作人员太多的计算资源当它爆裂时有螺纹。还要感谢您对内存问题的建议,我对整个程序的内存使用进行了基准测试,我认为内存不是瓶颈,我仍在研究其他可能的方法来平滑这个线程的 CPU 爆发。
  • 我认为随着时间的推移逐渐增加和减少线程的 CPU 使用率没有任何优势。 CPU 不像可以以不同速度行驶的汽车。而是 CPU 要么以其正常速度在使用,要么处于空闲状态;没有“半速跑”;如果您在 CPU 图表上看到 50%,这意味着 CPU 在一半的采样周期内处于使用状态,而另一半则处于空闲状态。此外,低优先级线程永远不会“窃取”高优先级线程的 CPU 周期。只要高优先级的线程想要运行,低优先级的线程就会被 CPU 踢掉。
  • 感谢您的解释!那我想我的程序可能还有一些其他问题会导致周期性变慢,我会调查一下,谢谢!
  • 什么是变量&m
  • &m 是一个错字;它应该是 &param。我已经修好了。
【解决方案2】:

确实,Linux 上调度优先级的情况对于进程与线程的应用是一个巨大的混乱。在规范级别,nicesetpriority 适用于进程,但 Linux 实际上并不支持这样做,因此它将参数解释为内核级别的线程 ID(与 pthread_t 不同,并且没有标准用户空间 API 来请求线程的内核级 tid!)。

您也许可以使用SCHED_IDLESCHED_BATCH 实现您想要的效果,但它们也不能正常工作。

【讨论】:

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