进程优先级与调度策略
基础部分
三种调度策略
- SCHED_OTHER 分时调度策略
- SCHED_FIFO 实时调度策略,先到先服务
- SCHED_RR 实时调度策略, 时间片轮转
RR和FIFO属于实时任务。创建时优先级大于0(1-99)。按照可抢占优先级调度算法进行。就绪态的实时任务立即抢占非实时任务。
两个函数可以获得线程设置的最高和最低优先级:
- int sched_get_priority_max(int policy); //获取实时优先级的最大值
- int sched_get_priority_min(int policy); //获取实时优先级的最小值
SCHED_OTHER不支持优先级使用;SCHED_FIFO/SCHED_RR支持优先级使用,分别为1和99。
设置与获取优先级的两个主要函数:
- int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param); //创建线程优先级
- int pthread_attr_getschedparam(pthread_attr_t *attr, const struct sched_param *param); //获取线程优先级
param.sched_priority = 51; //设置优先级
当系统创建线程时,默认线程是SCHED_OTHER。改变调度策略,通过如下函数:
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy); //设置线程调度策略
实战部分
例子
#include
#include
#include
static int get_thread_policy(pthread_attr_t *attr) {
int policy = 0;
int result = pthread_attr_getschedpolicy(attr, &policy);
assert(0 == result);
switch (policy) {
case SCHED_FIFO:
printf("[%s][%d] policy = SCHED_FIFO.\n", __FILE__, __LINE__);
break;
case SCHED_RR:
printf("[%s][%d] policy = SCHED_RR.\n", __FILE__, __LINE__);
break;
case SCHED_OTHER:
printf("[%s][%d] policy = SCHED_OTHER.\n", __FILE__, __LINE__);
break;
default:
break;
}
return policy;
}
static void show_thread_priority(pthread_attr_t *attr, int policy) {
int priority = sched_get_priority_max(policy);
assert(priority != -1);
printf("[%s][%d] max_priority = %d.\n", __FILE__, __LINE__, priority);
priority = sched_get_priority_min(policy);
assert(priority != -1);
printf("[%s][%d] min_priority = %d.\n", __FILE__, __LINE__, priority);
}
static int get_thread_priority(pthread_attr_t *attr) {
struct sched_param param;
int result = pthread_attr_getschedparam(attr, ¶m);
assert(0 == result);
printf("[%s][%d] priority = %d.\n", __FILE__, __LINE__, param.sched_priority);
return param.sched_priority;
}
static void set_thread_policy(pthread_attr_t *attr, int policy) {
int result = pthread_attr_setschedpolicy(attr, policy);
assert(0 == result);
get_thread_policy(attr);
return;
}
int main() {
pthread_attr_t attr;
struct sched_param sched;
int result = pthread_attr_init(&attr);
assert(0 == result);
int policy = get_thread_policy(&attr);
printf("[%s][%d] output current config of priority.\n", __FILE__, __LINE__);
show_thread_priority(&attr, policy);
printf("[%s][%d] output SCHED_FIFO of priority.\n", __FILE__, __LINE__);
show_thread_priority(&attr, SCHED_FIFO);
printf("[%s][%d] output SCHED_RR of priority.\n", __FILE__, __LINE__);
show_thread_priority(&attr, SCHED_RR);
printf("[%s][%d] output current config of priority.\n", __FILE__, __LINE__);
int priority = get_thread_priority(&attr);
printf("[%s][%d] set SCHED_FIFO policy.\n", __FILE__, __LINE__);
set_thread_policy(&attr, SCHED_FIFO);
printf("[%s][%d] set SCHED_RR policy.\n", __FILE__, __LINE__);
set_thread_policy(&attr, SCHED_RR);
printf("[%s][%d] restore current policy.\n", __FILE__, __LINE__);
set_thread_policy(&attr, policy);
result = pthread_attr_destroy(&attr);
assert(0 == result);
return 0;
}
运行结果
#include
#include
#include
#include
void threadFunc1() {
sleep(1);
int policy;
struct sched_param param;
pthread_getschedparam(pthread_self(), &policy, ¶m);
if (SCHED_OTHER == policy) {
printf("[%s][%d] policy = SCHED_OTHER.\n", __FILE__, __LINE__);
} else if (SCHED_FIFO == policy) {
printf("[%s][%d] policy = SCHED_FIFO.\n", __FILE__, __LINE__);
} else if (SCHED_RR == policy) {
printf("[%s][%d] policy = SCHED_RR.\n", __FILE__, __LINE__);
} else {
}
for(int i = 1; i < 11; i++) {
for (int j = 1; j < 400000000; j++) {
}
printf("[%s][%d] phreadFunc1.\n", __FILE__, __LINE__);
}
printf("[%s][%d] phreadFunc1 EXIT.\n", __FILE__, __LINE__);
}
void threadFunc2() {
sleep(1);
int policy;
struct sched_param param;
pthread_getschedparam(pthread_self(), &policy, ¶m);
if (SCHED_OTHER == policy) {
printf("[%s][%d] policy = SCHED_OTHER.\n", __FILE__, __LINE__);
} else if (SCHED_FIFO == policy) {
printf("[%s][%d] policy = SCHED_FIFO.\n", __FILE__, __LINE__);
} else if (SCHED_RR == policy) {
printf("[%s][%d] policy = SCHED_RR.\n", __FILE__, __LINE__);
} else {
}
for(int i = 1; i < 11; i++) {
for (int j = 1; j < 4000000; j++) {
}
printf("[%s][%d] phreadFunc2.\n", __FILE__, __LINE__);
}
printf("[%s][%d] phreadFunc2 EXIT.\n", __FILE__, __LINE__);
}
void threadFunc3() {
sleep(1);
int policy;
struct sched_param param;
pthread_getschedparam(pthread_self(), &policy, ¶m);
if (SCHED_OTHER == policy) {
printf("[%s][%d] policy = SCHED_OTHER.\n", __FILE__, __LINE__);
} else if (SCHED_FIFO == policy) {
printf("[%s][%d] policy = SCHED_FIFO.\n", __FILE__, __LINE__);
} else if (SCHED_RR == policy) {
printf("[%s][%d] policy = SCHED_RR.\n", __FILE__, __LINE__);
} else {
}
for(int i = 1; i < 11; i++) {
for (int j = 1; j < 4000000; j++) {
}
printf("[%s][%d] phreadFunc3.\n", __FILE__, __LINE__);
}
printf("[%s][%d] phreadFunc3 EXIT.\n", __FILE__, __LINE__);
}
int main() {
int i = getuid();
if (0 == i)
printf("[%s][%d] the current user is root.\n", __FILE__, __LINE__);
else
printf("[%s][%d] the current user is not root.\n", __FILE__, __LINE__);
pthread_t ppid1, ppid2, ppid3;
struct sched_param param;
pthread_attr_t attr1, attr2, attr3;
pthread_attr_init(&attr1);
pthread_attr_init(&attr2);
pthread_attr_init(&attr3);
param.sched_priority = 51;
pthread_attr_setschedpolicy(&attr3, SCHED_RR);
pthread_attr_setschedparam(&attr3, ¶m);
pthread_attr_setinheritsched(&attr3, PTHREAD_EXPLICIT_SCHED);
param.sched_priority = 22;
pthread_attr_setschedpolicy(&attr2, SCHED_RR);
pthread_attr_setschedparam(&attr2, ¶m);
pthread_attr_setinheritsched(&attr2, PTHREAD_EXPLICIT_SCHED);
pthread_create(&ppid3, &attr1, (void*)threadFunc3, NULL);
pthread_create(&ppid2, &attr2, (void*)threadFunc2, NULL);
pthread_create(&ppid1, &attr3, (void*)threadFunc1, NULL);
pthread_join(ppid3, NULL);
pthread_join(ppid2, NULL);
pthread_join(ppid1, NULL);
pthread_attr_destroy(&attr3);
pthread_attr_destroy(&attr2);
pthread_attr_destroy(&attr1);
return 0;
}
结果貌似不太对,原因待查:
总结
本文主要对调度策略的设置进行了两个例子编写。第二个例子与预期结果不一致,貌似并没有改变优先级,需要查询原因。
技术参考
https://ke.qq.com/webcourse/3294666/103425320#taid=11144559668118986&vid=5285890815288776379
https://zhuanlan.zhihu.com/p/381043183