进度优先级与调度策略


基础知识

Linux 内核当中有3中调度策略

  1. SCHED_OTHER 分时调度策略
  2. SCHED_FIFO 实时调度策略,先到先服务;
  3. 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,即普通任务调度的函数。

简单分析

#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);
    printf("policy is %d", iPlicy);
    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 -> Unkonwn .\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("\n Export 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 =GetThreadPolicyFunc(&pAttr);
    printf("Set thread policy.\n");

    printf("\n set sched_fifo policy.\n");
    SetThreadPolicyFunc(&pAttr,SCHED_FIFO);

    printf("\n set SCHED_RR policy.\n");
    SetThreadPolicyFunc(&pAttr,SCHED_RR);

    printf("\n Restore 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 TestThreadFunc() {
    sleep(1);
    int i ,j;
    int iPolicy;
    struct sched_param sParam;
    pthread_getschedparam(pthread_self(),&iPolicy,&sParam);
    if(iPolicy == SCHED_OTHER)
        printf("SCHED_OTHER.\n");
    if(iPolicy == SCHED_FIFO)
        printf("SCHED_FIFO.\n");
    if(iPolicy == SCHED_RR)
        printf("SCHED_RR test001.\n");
    for(i = 1; i<=5;i++)
    {
        for(j = 1; j<=5000000; j++){

        }
        printf("execute thread function 1.\n");
    }
    printf("Pthread 1 exit.\n\n");
}
void TestThread2Func() {
    sleep(2);
    int i ,j;
    int iPolicy;
    struct sched_param sParam;
    pthread_getschedparam(pthread_self(),&iPolicy,&sParam);
    if(iPolicy == SCHED_OTHER)
        printf("SCHED_OTHER.\n");
    if(iPolicy == SCHED_FIFO)
        printf("SCHED_FIFO.\n");
    if(iPolicy == SCHED_RR)
        printf("SCHED_RR test002.\n");
    for(i = 1; i<=6;i++)
    {
        for(j = 1; j<=6000000; j++){

        }
        printf("execute thread function 2.\n");
    }
    printf("Pthread 2  exit.\n\n");
}

void TestThread3Func() {
    sleep(3);
    int i ,j;
    int iPolicy;
    struct sched_param sParam;
    pthread_getschedparam(pthread_self(),&iPolicy,&sParam);
    if(iPolicy == SCHED_OTHER)
        printf("SCHED_OTHER.\n");
    if(iPolicy == SCHED_FIFO)
        printf("SCHED_FIFO.\n");
    if(iPolicy == SCHED_RR)
        printf("SCHED_RR test001.\n");
    for(i = 1; i<=7;i++)
    {
        for(j = 1; j<=7000000; j++){

        }
        printf("execute thread function 3.\n");
    }
    printf("Pthread 3 exit.\n\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 ppid1,ppid2,ppid3;
    struct sched_param sParam;
    pthread_attr_t pAttr1,pAttr2,pAttr3;
    pthread_attr_init(&pAttr1);
    pthread_attr_init(&pAttr2);
    pthread_attr_init(&pAttr3);
    sParam.sched_priority=31;
    pthread_attr_setschedpolicy(&pAttr2,SCHED_RR);

    pthread_attr_setschedparam(&pAttr2,&sParam);
    pthread_attr_setinheritsched(&pAttr2,PTHREAD_EXPLICIT_SCHED);

    sParam.sched_priority = 11;
    pthread_attr_setschedpolicy(&pAttr1,SCHED_RR);
    pthread_attr_setschedparam(&pAttr1,&sParam);
    pthread_attr_setinheritsched(&pAttr1,PTHREAD_EXPLICIT_SCHED);

    pthread_create(&ppid3,&pAttr3,(void *)TestThread3Func,NULL);
    pthread_create(&ppid2,&pAttr2,(void *)TestThread2Func,NULL);
    pthread_create(&ppid1,&pAttr1,(void *)TestThreadFunc,NULL);

    pthread_join(ppid3,NULL);
    pthread_join(ppid2,NULL);
    pthread_join(ppid1,NULL);



    return 0;
}

普通用户级别只能运行线程3,root级别1,2,3都能运行