进程优先级与调度策略

Posted 打工人打工魂打工人上人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程优先级与调度策略相关的知识,希望对你有一定的参考价值。

基础部分

三种调度策略

  • SCHED_OTHER 分时调度策略
  • SCHED_FIFO 实时调度策略,先到先服务
  • SCHED_RR 实时调度策略, 时间片轮转

RR和FIFO属于实时任务。创建时优先级大于0(1-99)。按照可抢占优先级调度算法进行。就绪态的实时任务立即抢占非实时任务。
两个函数可以获得线程设置的最高和最低优先级:

  1. int sched_get_priority_max(int policy); //获取实时优先级的最大值
  2. int sched_get_priority_min(int policy); //获取实时优先级的最小值

SCHED_OTHER不支持优先级使用;SCHED_FIFO/SCHED_RR支持优先级使用,分别为1和99。
设置与获取优先级的两个主要函数:

  1. int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param); //创建线程优先级
  2. 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 <pthread.h>
#include <sched.h> 
#include <assert.h>

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, &param);
    
    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 <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>

void threadFunc1() 
    sleep(1);
    int policy;
    struct sched_param param;
    pthread_getschedparam(pthread_self(), &policy, &param);
    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, &param);
    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, &param);
    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, &param);
    pthread_attr_setinheritsched(&attr3, PTHREAD_EXPLICIT_SCHED);

    param.sched_priority = 22;
    pthread_attr_setschedpolicy(&attr2, SCHED_RR);
    pthread_attr_setschedparam(&attr2, &param);
    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

以上是关于进程优先级与调度策略的主要内容,如果未能解决你的问题,请参考以下文章

Linux 内核进程优先级与调度策略 ① ( SCHED_FIFO 调度策略 | SCHED_RR 调度策略 | 进程优先级 )

浅析Linux下进程的调度策略与优先级

Android 进程管理篇(五)-调度策略与优先级

Linux 内核进程优先级与调度策略 ① ( SCHED_FIFO 调度策略 | SCHED_RR 调度策略 | 进程优先级 )

进程优先级与调度策略

Linux 操作系统原理 — 用户进程与内核线程的调度策略与切换开销