线程的调度策略
线程的调度策略
-
一般而言这一张针对于CPU为单核的操作系统,多核的操作系统可以让线程一起运行,然而单核的操作系统只能让线程轮流运行。
-
线程的静态优先级
静态优先级(刚开始设定的优先级)的范围是0~99,越高的优先级数字就越大。在设置线程的静态优先级之前,需要了解线程继承。
-
线程的继承
-
意思是在线程被创建的时候,是否继承当前创建线程的优先级或者属性。
-
初始化线程属性
-
int pthread_attr_init(pthread_attr_t *attr);
//第一个参数是初始化线程的属性
//返回值,返回0成功,失败返回错误码
int pthread_attr_destroy(pthread_attr_t *attr);
//第一个参数是摧毁线程的属性
//返回值,返回0成功,失败返回错误码
- 设置线程属性(继承与不继承)
int pthread_attr_setinheritsched(pthread_attr_t *attr,int inheritsched);
//第一个参数是需要设置参数的属性
//第二个参数是线程是否设置需要继承
PTHREAD_INHERIT_SCHED //继承
PTHREAD_EXPLICIT_SCHED //不继承
//返回值,成功返回0,失败返回错误码。
int pthread_attr_getinheritsched(const pthread_attr_t *attr,int *inheritsched);
//第一个参数是需要获取参数的属性
//第二个参数是线程属性获取,需要一个变量的指针
PTHREAD_INHERIT_SCHED //继承
PTHREAD_EXPLICIT_SCHED //不继承
//返回值,成功返回0,失败返回错误码。
线程是可以继承在那个线程创建这个线程的属性的,如果选择继承,那么这个线程的属性将会被继承在下面。
下面可以设置线程的调度策略。
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
//第一个参数是需要设置线程的属性
//第二个参数是线程需要设置的选项
SCHED_FIFO //先到先服务,先创建,先执行
SCHED_RR //时间片轮询策略,可以将线程的时间分段
SCHED_OTHER //会选择一个运行时间最小的线程优先执行,依次执行(静态优先级必须为0)
//返回值,返回0成功,失败返回错误码。
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
//第一个参数是需要获取线程的属性
//第二个参数是线程需要获取的选项
SCHED_FIFO //先到先服务,先创建,先执行
SCHED_RR //时间片轮询策略,可以将线程的时间分段
SCHED_OTHER //会选择一个运行时间最小的线程优先执行,依次执行(静态优先级必须为0)
//返回值,返回0成功,失败返回错误码。
- 设置线程的优先级
int pthread_attr_setschedparam(pthread_attr_t *attr,const struct sched_param *param);
//第一个参数是需要设置的线程的属性
//第二个参数是一个结构体参数如下
struct sched_param {
int sched_priority; /* Scheduling priority */
//这个是线程的静态优先级范围是0~99,想要设置优先级必须设置为不继承
};
//返回值,返回0成功,失败返回错误码。
int pthread_attr_getschedparam(const pthread_attr_t *attr,struct sched_param *param);
//第一个参数是需要获取的线程的属性
//第二个参数是一个结构体参数如下
struct sched_param {
int sched_priority; /* Scheduling priority */
//这个是线程的静态优先级范围是0~99
};
//返回值,返回0成功,失败返回错误码。
-
静态优先级为0的是默认。
-
Example
//线程A优先级高
void *taskA(void * arg)
{
while(1);
}
//线程B优先级低
void *taskB(void * arg)
{
while(1);
}
int main()
{
pthread_attr_t attr;
pthread_attr_init(&attr);
//设置为不继承(想要设置优先级必须设置为不继承)
pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED);
//先到先服务
pthread_attr_getschedpolicy(&attr, SCHED_FIFO);
//设置优先级
struct sched_param param;
param.sched_priority = 46;//设置为46
pthread_attr_getschedparam(&attr,¶m);
pthread_t pthread;
//创建线程B
pthread_create(&pthread, &attr, taskB, NULL);
param.sched_priority = 66;//设置为66
pthread_t pthread;
//创建线程A
pthread_create(&pthread, &attr, taskA, NULL);
return 0;
}
上述的例子,如果在单核的情况下的的话,即使是线程B先执行,结果也是A先执行。
需要注意的是,在单核的情况下,线程A线程执行的过程中,如果遇到了阻塞,或者挂起等,那么CPU会立刻执行线程B(等A不阻塞或者挂起时,然后执行线程A会返回到就绪态)
- 动态优先级
动态优先级有一个叫做nice值,这是设置动态优先级的函数,动态优先级是在线程内部设置的,动态优先级和静态优先级不一样,动态优先级的范围是(-20~19),优先级越高数字越低最高的优先级是-20,最低的优先级是19。
int nice(int incr);
//第一个参数是设置的动态优先级-20~19
//返回值,成功返回非0,失败返回-1
这个函数直接在线程内部调用即可,注意线程的调度策略不能是SCHED_OTHER。

浙公网安备 33010602011771号