我在 Linux 中使用 pthread。我想通过设置参数来提高线程优先级
sched_param.priority
。但是,我在网上找不到太多关于我可以设置的线程优先级范围的信息,或者关于线程优先级的描述。
另外,我想知道相对线程优先级,因为我不想将线程优先级设置得太高并导致操作系统停止。有人可以帮我解决这个问题吗?
默认的 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
,因为这不需要root权限。
警告:错误使用实时调度策略可能会导致系统挂起。这就是为什么你需要 root 权限才能执行此类操作。
为了确定您的机器的功能,您可以使用
chrt
工具
util-linux
包。 $ 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%(就我而言)。
编辑:介绍
nice
、SCHED_BATCH
、SCHED_IDLE
和chrt
工具。为了准确! :)
来自 levif 的当前答案(推荐 SCHED_BATCH)对于 Linux 上当前的 NPTL 线程实现来说是不正确的(您可以通过运行“getconf GNU_LIBPTHREAD_VERSION”来检查您的内核具有哪个实现)。
在今天的内核中,只有实时调度策略允许设置 sched_priority - 对于非 RT 策略(SCHED_OTHER、SCHED_BATCH 和 SCHED_IDLE),它始终为 0。您对非 RT 策略的唯一选择是设置“好的”值,例如通过设置优先级()。然而,对于设置“nice”所期望的确切行为,并没有很好的规范,至少在理论上,它可能因内核版本而异。对于当前的 Linux 内核,“nice”具有与优先级类似的非常强的效果,因此您几乎可以互换使用它。为了增加线程的调度频率,您需要降低您的“nice”值。这需要 CAP_SYS_NICE 功能(通常是 root,但不一定,请参阅 http://man7.org/linux/man-pages/man7/capability.7.html 和 http://man7.org/linux/man-页/man3/cap_set_proc.3.html)。
事实上,SCHED_BATCH 是为与提问者要求的“相反”情况而设计的:它是为 CPU 密集型、长时间运行的作业而设计的,可以承受“较低”优先级。它告诉调度程序稍微惩罚线程的唤醒优先级。 同时回答之前的评论之一。是的,坏消息是 POSIX.1 规范说“nice”影响进程,而不是单个线程。好消息是 Linux 线程实现(NPTL 和原始 Linux 线程)违反了规范并允许它影响单个线程。我觉得很有趣的是,这经常在手册页的“BUGS”部分中被提及。我想说这个错误存在于 POSIX.1 规范中,该规范应该允许这种行为,而不是存在于尽管有规范却被迫提供这种行为的实现中,并且是故意这样做的。换句话说 - 不是错误。 其中大部分内容在 sched(7) 手册页中有详细说明(由于某种原因,该手册页未在我的 Fedora 20 系统上提供):
http://man7.org/linux/man-pages/man7/sched.7.html如果您确实想影响 sched_priority,您可以查看实时策略,例如 SCHED_RR)。
POSIX 定义了一个查询,因此您可以向操作系统询问优先级的有效范围。
int sched_get_priority_max(int policy);
int sched_get_priority_min(int policy);
不要指望提高优先级会阻塞机器。事实上,除非您已经使用了 100% 的 CPU 周期,否则不要指望它会执行任何操作。如果查询告诉您没有优先级高于默认值,请不要感到惊讶。