参考《多线程编程指南》
1.POSIX 标准指定了三种调度策略:先入先出策略 (SCHED_FIFO)、循环策略 (SCHED_RR) 和自定
义策略 (SCHED_OTHER)。SCHED_FIFO 是基于队列的调度程序,对于每个优先级都会使用不同
的队列。SCHED_RR 与 FIFO 相似,不同的是前者的每个线程都有一个执行时间配额。
SCHED_FIFO 和 SCHED_RR 是对 POSIX Realtime 的扩展。SCHED_OTHER 是缺省的调度策略。
提供了两个调度范围:进程范围 (PTHREAD_SCOPE_PROCESS) 和系统范围
(PTHREAD_SCOPE_SYSTEM)。具有不同范围状态的线程可以在同一个系统甚至同一个进程中共
存。进程范围只允许这种线程与同一进程中的其他线程争用资源,而系统范围则允许此类
线程与系统内的其他所有线程争用资源。实际上,从 Solaris 9 发行版开始,系统就不再区分
这两个范围。
《posix多线程程序设计》:
SCHED_FIFO:允许一个线程一直运行直到有更高优先级的线程准备好或者自愿阻塞自己。在SCHED_FIFO调度策略下,当一个线程准备好时,除非有平等或者更高优先级的线程在运行,否则它会很快开始运行。
SCHED_RR:即轮询与SCHED_FIFO不同的地方是:在SCHED_RR调度策略下,当一个线程运行了一个固定的时间段(时间片间隔)后还没有阻塞,这时候如果有相同的优先级(SCHED_FIFO或者SCHED_RR)线程准备好时,运行中的线程将被抢占以使准备好的同优先级的线程得以得到运行的机会。
2.使用pthread_attr_getschedpolicy(pthread_attr_t *attr, int *policy)得到线程调度策略;
使用pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)设置线程调度策略;
posix指定3种调度策略属性:SCHED_FIFO, SCHED_RR, SCHED_OTHER.
SCHED_FIFO 和 SCHED_RR 在 POSIX 标准中是可选的,而且仅用于实时线程。
一个简单的测试代码:
#include "../errors.h" #include <sched.h>
int main(int argc, char **argv) { pthread_attr_t attr; int status = 0, policy = 0;
status = pthread_attr_init(&attr); if(status != 0){ err_abort(status, "attr init"); }
status = pthread_attr_getschedpolicy(&attr, &policy); if(status != 0){ err_abort(status, "pthread_attr_getschedpolicy"); }
switch(policy){ case SCHED_FIFO: printf("SCHED_FIFO\n"); break; case SCHED_RR: printf("SCHED_RR\n"); break; case SCHED_OTHER: printf("SCHED_OTHER\n"); break; default: printf("default\n"); break; }
exit(0); }
运行结果:
[xxxx@localhost chap5]$ ./a.out SCHED_OTHER
|
3.使用 pthread_attr_setinheritsched(3C) 设置继承的调度策略。
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit);
inherit 值 PTHREAD_INHERIT_SCHED 表示新建的线程将继承创建者线程中定义的调度策略。将
忽略在 pthread_create() 调用中定义的所有调度属性。如果使用缺省值
PTHREAD_EXPLICIT_SCHED,则将使用 pthread_create() 调用中的属性。
使用pthread_attr_getinheritsched(pthread_attr_t *attr, int *)获取继承的调度策略。
man pthread_attr_setinheritsched:
DESCRIPTION
The pthread_attr_getinheritsched(), and pthread_attr_setinheritsched() functions, respectively, shall get and set the inheritsched attribute in the attr
argument.
When the attributes objects are used by pthread_create(), the inheritsched attribute determines how the other scheduling attributes of the created
thread shall be set.
PTHREAD_INHERIT_SCHED
Specifies that the thread scheduling attributes shall be inherited from the creating thread, and the scheduling attributes in this attr argument
shall be ignored.
PTHREAD_EXPLICIT_SCHED
Specifies that the thread scheduling attributes shall be set to the corresponding values from this attributes object.
The symbols PTHREAD_INHERIT_SCHED and PTHREAD_EXPLICIT_SCHED are defined in the
header.
The following thread scheduling attributes defined by IEEE Std 1003.1-2001 are affected by the inheritsched attribute: scheduling policy ( schedpolicy),
scheduling parameters ( schedparam), and scheduling contention scope ( contentionscope).
实例1:
#include "../errors.h" #include <sched.h>
int main(int argc, char **argv) { int status, inherit; pthread_attr_t attr;
status = pthread_attr_init(&attr); if(status != 0){ err_abort(status, "pthread_attr_init"); }
status = pthread_attr_getinheritsched(&attr, &inherit); switch(inherit){ case PTHREAD_EXPLICIT_SCHED: printf("PTHREAD_EXPLICIT_SCHED\n"); break; case PTHREAD_INHERIT_SCHED: printf("PTHREAD_INHERIT_SCHED\n"); break; default: break; }
exit(0); }
运行结果:
[xxxx@localhost chap5]$ ./a.out PTHREAD_INHERIT_SCHED
|
4.设置调度参数:
pthread_attr_setschedparam(3C) 可以设置调度参数。
int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
调度参数是在 param 结构中定义的。仅支持优先级参数。新创建的线程使用此优先级运行。
可以采用两种方式之一来管理 pthreads 优先级:
(1).创建子线程之前,可以设置优先级属性
(2).可以更改父线程的优先级,然后再将该优先级改回来
获取调度参数:
int pthread_attr_getschedparam(pthread_attr_t *attr, const struct sched_param *param);
5.竞争范围和分配域:
使用 pthread_attr_setscope(3C) 建立线程的争用范围(PTHREAD_SCOPE_SYSTEM 或
PTHREAD_SCOPE_PROCESS)。 使用 PTHREAD_SCOPE_SYSTEM 时,此线程将与系统中的所有线程
进行竞争。使用 PTHREAD_SCOPE_PROCESS 时,此线程将与进程中的其他线程进行竞争。
注 – 只有在给定进程中才能访问这两种线程类型。
int pthread_attr_setscope(pthread_attr_t *attr, int scope);
int pthread_attr_getscope(pthread_attr_t *attr, int *scope);