基础知识
- Linux 内核当中有 3 种调度策略:
- SCHED_OTHER 分时调度策略;
- SCHED_FIFO 实时调度策略,先到先服务;
- SCHED_RR 实时调度策略,时间片轮转。
如果有相同优先级的实时进程(根据优先级计算的调度权值是一样的)已经准备好,FIFO 时必须等待该进程主动放弃之后才可以运行这个优先级相同的任务。而 RR 可以每个任务都执行一段时间。
- 获取线程设置的最高和最低优先级函数
int sched_get_priority_max(int policy)
获取实时优先级的最大值;int sched_get_priority_min(int policy)
获取实时优先级的最小值;
SCHED_OTHER
它 不 支 持 优 先 级 使 用 , 而SCHED_RR/SCHED_FIFO
支持优先级使用,它们分别为 1-99,数值越大优先级越高。
实时调度策略(SCHED_FIFO/SCHED_RR)优先级最大值为99;普通调度策略
(SCHED_NORMAL/SCHED_BATCH/SCHED_IDLE),始终返回0,即普通任务调度的函数。
-
设置和获取优先级的2个主要核心参数
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)
;获取线程优先级;
struct sched_param { int __sched_priority; // 所有设定的线程优先级 } param.sched_priority = 11; // 设置优先级
-
当操作系统创建线程时,默认线程是 SCHED_OTHER,我们也可以通过改变调度策略,使用如下函数:
int pthread_attr_setschedpolicy(pthread_attr_t* attr, int policy);
设置线程调度策略;
基础案例分析
- 操作系统所支持优先级测试程序分析:
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <assert.h>
static int GetThreadPolicyFunc(pthread_attr_t *pAttr)
{
int iPlicy;
int igp=pthread_attr_getschedpolicy(pAttr,&iPlicy);
assert(igp==0);
switch (iPlicy)
{
case SCHED_FIFO:
printf("Policy is --> SCHED_FIFO.\n");
break;
case SCHED_RR:
printf("Policy is --> SCHED_RR.\n");
break;
case SCHED_OTHER:
printf("Policy is --> SCHED_OTHER.\n");
break;
default:
printf("Policy is --> Unknown.\n");
break;
}
return iPlicy;
}
static void PrintThreadPriorityFunc(pthread_attr_t *pAttr,int iPolicy)
{
int iPriority=sched_get_priority_max(iPolicy);
assert(iPriority!=-1);
printf("Max_priority is : %d\n",iPriority);
iPriority=sched_get_priority_min(iPolicy);
assert(iPriority!=-1);
printf("Min_priority is : %d\n",iPriority);
}
static int GetThreadPriorityFunc(pthread_attr_t *pAttr)
{
struct sched_param sParam;
int irs=pthread_attr_getschedparam(pAttr,&sParam);
assert(irs==0);
printf("Priority=%d\n",sParam.__sched_priority);
return sParam.__sched_priority;
}
static void SetThreadPolicyFunc(pthread_attr_t *pAttr,int iPolicy)
{
int irs=pthread_attr_setschedpolicy(pAttr,iPolicy);
assert(irs==0);
GetThreadPolicyFunc(pAttr);
}
int main(int argc,char *argv[])
{
pthread_attr_t pAttr;
struct sched_param sched;
int irs=pthread_attr_init(&pAttr);
assert(irs==0);
int iPlicy=GetThreadPolicyFunc(&pAttr);
printf("\nExport current Configuration of priority.\n");
PrintThreadPriorityFunc(&pAttr,iPlicy);
printf("\nExport SCHED_FIFO of prioirty.\n");
PrintThreadPriorityFunc(&pAttr,SCHED_FIFO);
printf("\nExport SCHED_RR of prioirty.\n");
PrintThreadPriorityFunc(&pAttr,SCHED_RR);
printf("\nExport priority of current thread.\n");
int iPriority=GetThreadPriorityFunc(&pAttr);
printf("Set thread policy.\n");
printf("\nSet SCHED_FIFO policy.\n");
SetThreadPolicyFunc(&pAttr,SCHED_FIFO);
printf("\nSet SCHED_RR policy.\n");
SetThreadPolicyFunc(&pAttr,SCHED_RR);
printf("\nRestore current policy.\n");
SetThreadPolicyFunc(&pAttr,iPlicy);
irs=pthread_attr_destroy(&pAttr);
assert(irs==0);
return 0;
}
- 简单线程调度策略,我们创建三个线程,默认创建的线程它的调度策略为SCHED_OTHER,另外两个线程调度策略为 SCHED_RR/FIFO:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
void ThreadFunc1() {
sleep(1);
int i, j;
int policy;
struct sched_param param;
pthread_getschedparam(pthread_self(), &policy, ¶m);
switch (policy) {
case SCHED_OTHER:
printf("SCHED_OTHER\n");
break;
case SCHED_FIFO:
printf("SCHED_FIFO\n");
case SCHED_RR:
printf("SCHED_RR Thread1\n");
default:
break;
}
for(i = 1; i <= 5; i++){
for(j = 1; j <= 5000000; j++){}
printf("Execute thread function 1.\n");
}
printf("ThreadFunc1 Exit\n");
}
void ThreadFunc2() {
sleep(2);
int policy;
struct sched_param param;
pthread_getschedparam(pthread_self(), &policy, ¶m);
switch(policy) {
case SCHED_OTHER:
printf("SCHED_OTHER\n");
break;
case SCHED_FIFO:
printf("SCHED_FIFO\n");
break;
case SCHED_RR:
printf("SCHED_RR Thread2");
break;
}
for(int i = 1; i <= 6; i++){
for(int j = 1; j <= 6000000; j++){}
printf("Execute thread function 2.\n");
}
printf("ThreadFunc2 Exit\n");
}
void ThreadFunc3() {
sleep(3);
int policy;
struct sched_param param;
pthread_getschedparam(pthread_self(), &policy, ¶m);
switch(policy) {
case SCHED_OTHER:
printf("SCHED_OTHER\n");
break;
case SCHED_FIFO:
printf("SCHED_FIFO\n");
break;
case SCHED_RR:
printf("SCHED_RR\n");
break;
}
for(int i = 1; i <= 7; i++) {
for(int j = 0; j <= 7000000; j++){}
printf("Execute thread function 3.\n");
}
printf("ThreadFunc3 Exit\n");
}
int main(int argc, char* argv[]) {
int i = 0;
i = getuid();
if(i == 0) {
printf("The current user is root.\n\n");
}
else {
printf("The current user is not root.\n\n");
}
pthread_t pid1, pid2, pid3;
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 = 31;
pthread_attr_setschedpolicy(&attr2, SCHED_RR);
pthread_attr_setschedparam(&attr2, ¶m);
pthread_attr_setinheritsched(&attr2, PTHREAD_EXPLICIT_SCHED);
param.sched_priority = 11;
pthread_attr_setschedpolicy(&attr1, SCHED_FIFO);
pthread_attr_setschedparam(&attr1, ¶m);
pthread_attr_setinheritsched(&attr1, PTHREAD_EXPLICIT_SCHED);
pthread_create(&pid3, &attr3, (void*)ThreadFunc3, NULL);
pthread_create(&pid2, &attr2, (void*)ThreadFunc2, NULL);
pthread_create(&pid1, &attr1, (void*)ThreadFunc1, NULL);
pthread_join(pid3, NULL);
pthread_join(pid2, NULL);
pthread_join(pid1, NULL);
pthread_attr_destroy(&attr3);
pthread_attr_destroy(&attr2);
pthread_attr_destroy(&attr1);
return 0;
}
- 超级用户运行