我正在尝试以向后兼容的方式从 C 重新实现 RobotC API(尽管有些细节更适合 C++,或者使用 C++ 会更容易),并尝试重新实现他们的多线程 API以某种便携的方式,所以我尝试使用sched_get_priority_max(2)
和sched_get_priority_min(2)
。但一方面nice(1)
,sched(7)
优先级介于 -20(最高优先级)和 19(较低优先级)之间,另一方面,前面的手册页指出:
[…]优先级数值较高的进程会先于优先级数值较低的进程进行调度。因此,sched_get_priority_max() 返回的值将大于 sched_get_priority_min() 返回的值
这意味着相反:正值具有较高优先级,负值具有较低优先级(它还给出了优先级在 1 到 99 之间的实时策略的示例)。
sched_get_priority_max
和将返回什么_min
?我应该和什么一起使用pthread_attr_setschedparam(3)
?
我有三个值定义我的自定义优先级范围:低优先级(kLowPriority
,设置为 0)、高优先级(kHighPriority
,设置为 255)和默认优先级(kDefaultPriority
,设置为 7)。理想情况下,我认为对于具有默认值的调度策略,默认值为 0,kDefaultPriority
/7 应该变为 0,kHighPriority
/255 为最高优先级(19?99?无论sched_get_priority_max(3)
返回什么)或者可能是在没有特权的情况下可以分配的最高优先级?然后kLowPriority
是0 ± kDefaultPriority
,或者是最低优先级……哪个更合理?
目前我想我这样做:
pthread_attr_t attr;
pthread_t thread;
struct sched_param param;
const int policy = sched_getscheduler(0),
sched_high_prio = sched_get_priority_max(policy), // 19,
sched_low_prio = sched_get_priority_min(policy), // -20,
sched_range_prio = sched_high_prio - sched_low_prio;
pthread_attr_init (&attr);
pthread_attr_getinheritsched(&attr, PTHREAD_INHERIT_SCHED);
pthread_attr_getschedparam (&attr, ¶m);
param.sched_priority = -(((nTaskPriority
- kLowPriority) * sched_range_prio
/ kHighPriority) + sched_low_prio
- kDefaultTaskPriority);
PS:我不确定询问有关 POSIX API 的问题的最佳地点是这里还是堆栈溢出,所以我正在做这两件事,请删除我的帖子,或者如果您认为它在错误的地方,请要求我删除。编辑:所以帖子已删除。
答案1
我认为您正在寻找一个可移植的答案,但是理解这一点的一个好的开始是查看 Linux 上的行为,如联机帮助页中所述sched(7)
,在“调度策略”部分:
调度程序是决定CPU接下来执行哪个可运行线程的内核组件。每个线程都有一个关联的调度策略和一个静止的调度优先级, 调度优先级。调度程序根据调度策略和系统上所有线程的静态优先级的知识做出决策。
对于在正常调度策略之一(
SCHED_OTHER
、SCHED_IDLE
、SCHED_BATCH
)下调度的线程,调度优先级不用于调度决策(必须指定为 0)。在实时策略之一 (
SCHED_FIFO
,SCHED_RR
) 下调度的进程具有调度优先级值范围为 1(低)到 99(高)。 (正如数字所暗示的,实时线程总是比普通线程具有更高的优先级。)请注意:POSIX.1 要求实现仅支持实时策略的至少 32 个不同优先级,并且某些系统仅提供此功能最低限度。便携式程序应该使用sched_get_priority_min(2)和 sched_get_priority_max(2)找出特定政策支持的优先事项范围。
也可以看看POSIX 文档pthread_setschedparam
,它只需要三个策略(SCHED_OTHER
、SCHED_FIFO
和SCHED_RR
),并声明第一个策略下的行为是实现定义的。
因此,如果您想使用可移植的优先级来调度线程,则需要首先使用适当的策略(先进先出或循环)。然后确定值的范围,并设置适当的优先级。线程和进程通过降低优先级来调度:具有较高优先级的线程将首先运行。
在 Linux 上,默认行为(根据 POSIX 实现定义)使用动态优先级,该优先级是根据nice
值以及给定线程运行的频率来计算的。不是已安排。在 Linux 上,该nice
值确定优先级从低到高,因此 -20 是最高优先级,19 是最低优先级。 POSIX 描述nice
为每个进程的值,但在 Linux 上它是每个线程的,因此您可以用来在那里调度线程(但这不可移植)。