基础知识
- 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;
}
- 超级用户运行