如何在pthread中提高线程优先级?

69

我正在Linux中使用pthread。我想通过设置参数来增加线程优先级。然而,我在网上找不到关于我可以设置的线程优先级范围或线程优先级描述的信息。

此外,我想了解相对线程优先级,因为我不希望将线程优先级设置得太高,导致操作系统停止运行。有人能帮我吗?

3个回答

66

Linux默认的调度策略是SCHED_OTHER,这个策略没有优先级选择,但可以在策略内部调整nice等级。

您需要使用函数pthread_setschedparam(请参见man sched_setscheduler)切换到另一个调度策略

'正常'的调度策略:(来自sched_setscheduler(2)

   SCHED_OTHER   the standard round-robin time-sharing policy;
   SCHED_BATCH   for "batch" style execution of processes; and
   SCHED_IDLE    for running very low priority background jobs.

实时调度策略:

   SCHED_FIFO    a first-in, first-out policy; and
   SCHED_RR      a round-robin policy.

在你的情况下,也许可以使用SCHED_BATCH,因为这不需要根权限。

警告: 错误使用实时调度策略可能会挂起您的系统。这就是为什么您需要根权限进行此类操作的原因。

为了确保您的机器能够胜任,您可以使用util-linux软件包中的chrt工具。例如:

$ chrt -m 
SCHED_OTHER min/max priority    : 0/0
SCHED_FIFO min/max priority     : 1/99
SCHED_RR min/max priority       : 1/99
SCHED_BATCH min/max priority    : 0/0
SCHED_IDLE min/max priority     : 0/0

一个我经常使用的减少浪费时间的方法:

alias batchmake='time chrt --batch 0 make --silent'

在保持用户权限的情况下,这将使 make 提速 15%(在我的情况下)。

编辑:介绍 niceSCHED_BATCHSCHED_IDLEchrt 工具。为了准确起见!:)


1
关于SCHED_OTHER,这并不完全正确,因为“nice level”仍会生效。 - Hasturkun
你不需要 root 权限,只需要设置 rlimits 以便您可以设置的最大 prio >0。 - Spudd86
2
@Spudd86:当然,人们可以调整系统文件limits.conf(在FC的/etc/security/目录下)来增加硬限制值,然后作为标准用户使用setrlimit()。在其他情况下,这对于实时音频混合是必不可少的。这一点被遗漏了,我会进行编辑以修复。 - levif
POSIX.1规范指出nice影响整个程序。然而,Linux打破了规范(这是应该的!)以便使nice影响单个线程。请参阅我在此线程中的答案以获取更多详细信息。 - BobDoolittle
SCHED_BATCH具有相反的效果。有关更多详细信息,请参阅我对此问题的答案。 - BobDoolittle
显示剩余4条评论

40

levif目前的答案(推荐SCHED_BATCH)对于Linux上当前的NPTL线程实现是不正确的(您可以通过运行“getconf GNU_LIBPTHREAD_VERSION”来检查内核使用的实现方式)。

在当今内核中,只有实时调度策略允许设置sched_priority - 非实时策略(SCHED_OTHER、SCHED_BATCH和SCHED_IDLE)的sched_priority始终为0。非实时策略的唯一选择是通过setpriority()设置“nice”值。然而,对于设置“nice”的确切行为没有很好的规范,并且至少在理论上,它可能会因内核版本而异。对于当前的Linux内核,“nice”具有类似于优先级的非常强的影响,因此您几乎可以互换使用它。为了增加线程调度的频率,您需要降低“nice”值。这需要CAP_SYS_NICE功能(通常为root,但不一定,请参见http://man7.org/linux/man-pages/man7/capabilities.7.htmlhttp://man7.org/linux/man-pages/man3/cap_set_proc.3.html)。
事实上,SCHED_BATCH是为与问题提出者请求相反的情况而设计的:它是为CPU密集型、长时间运行的作业设计的,可以接受较低的优先级。它告诉调度程序略微惩罚线程的唤醒优先级。
此外,回答早期评论之一(我还没有足够的声望来回应评论 - 对这个答案的一些赞同会有所帮助 :))。是的,不幸的消息是,POSIX.1规范说'nice'影响进程,而不是单个线程。好消息是,Linux线程实现(包括NPTL和原始Linux线程)打破了规范,并允许其影响单个线程。我觉得有趣的是,这经常在手册页的“BUGS”部分中指出。我会说错误在于POSIX.1规范,它应该允许这种行为,而不是强制实现这种行为的实现,他们知道并故意这样做。换句话说-不是一个bug。
大多数内容都在sched(7)手册页上详细说明(由于某种原因,在我的Fedora 20系统上没有提供): http://man7.org/linux/man-pages/man7/sched.7.html 如果你真的想改变sched_priority,你可以看一下实时策略,比如SCHED_RR。

“当前的NPTL线程实现”是什么/曾经是什么?我需要与旧目标上“getconf”的输出进行比较。 - jhfrontz
4
NTPL(Native POSIX Threads Library)是当前Linux线程实现的名称。它不同于最初使用多个进程模拟多线程行为的线程实现。NTPL在Linux 2.6中引入。有关更多详细信息和历史,请参见此处:https://en.m.wikipedia.org/wiki/Native_POSIX_Thread_Library - BobDoolittle
与 Linus 的旧版愚蠢实现不同的是,他使用堆栈指针来查找当前运行的线程,因此可以使用更少的内核支持来实现。但是该实现非常原始,纤程/绿色线程将堆栈更改为 malloc 分配的内存段时会崩溃。幸运的是,它很快被移除了。 - Lothar

29

POSIX定义了一个查询,因此您可以向操作系统询问优先级的有效范围。

int sched_get_priority_max(int policy);

int sched_get_priority_min(int policy);

不要期望提高优先级会使机器瘫痪。实际上,除非您已经使用了100%的CPU周期,否则不要期望它会有任何作用。如果查询告诉您没有比默认优先级更高的优先级,请不要感到惊讶。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接