linux设置多线程的调度策略与优先级


目录
  • 1. Linux内核的三种调度策略
  • 2. 线程的调度策略相关 API -
  • 3. 当前调度策略支持的优先级范围 API
  • 4. 线程优先级设置 API
  • 5.测试代码
  • 6.扩展接口

1. Linux内核的三种调度策略

  1. SCHED_OTHER 分时调度策略
  2. SCHED_FIFO 实时调度策略,先到先服务。一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃
  3. SCHED_RR 实时调度策略,时间片轮转。当进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平。

2. 线程的调度策略相关 API -

系统创建线程时,默认是 SCHED_OTHER。如果我们要改变线程的调度策略的话,可以通过下面的这个函数实现。

#include 
//set/get  scheduling  policy  attribute  in thread attributes object
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);

//attr: 线程属性的结构体指针
//policy: SCHED_FIFO, SCHED_RR, and SCHED_OTHER

3. 当前调度策略支持的优先级范围 API

#include 

int sched_get_priority_max(int policy);
int sched_get_priority_min(int policy);

/*
Supported policy values are SCHED_FIFO, SCHED_RR, SCHED_OTHER, SCHED_BATCH, SCHED_IDLE, and SCHED_DEAD‐LINE.  Further details about these policies can be found in sched(7).

Processes with numerically higher priority values are scheduled before processes with numerically  lower  priority  values.

Thus, the value returned by sched_get_priority_max() will be greater than the value returned by sched_get_priority_min().

Linux allows the static priority range 1 to 99 for the SCHED_FIFO and SCHED_RR policies, and the priority 0 for the remain‐ing policies.  Scheduling priority ranges for the various policies are not alterable.

数字越大,线程的优先级越高。
对于SCHED_FIFO and SCHED_RR policies,优先级数字是 1 - 99
其它调度策略的优先级一直为0
*/

4. 线程优先级设置 API

#include 
//set/get  scheduling  parameter  attributes in thread attributes object
int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);

//Compile and link with -pthread.
//Scheduling parameters are maintained in the following structure:
struct sched_param {
    int sched_priority;     /* Scheduling priority */
};

5.测试代码

#include 
#include 
#include 
#include 

int get_thread_sched_policy(const pthread_attr_t *attr)
{
    int sched_policy;
    int ret = pthread_attr_getschedpolicy(attr, &sched_policy);
    assert(ret == 0);

    switch (sched_policy)
    {
    case SCHED_FIFO:
        printf("sched_policy = SCHED_FIFO\n");
        break;
    case SCHED_RR:
        printf("sched_policy = SCHED_RR\n");
        break;
    case SCHED_OTHER:
        printf("sched_policy = SCHED_OTHER\n");
        break;
    default:
        break;
    }
    return sched_policy;
}

int set_thread_sched_policy(pthread_attr_t *attr, const int policy)
{
    int ret = pthread_attr_setschedpolicy(attr, policy);
    assert(ret == 0);
    return ret;
}

int get_sched_policy_prior_max(const int policy)
{
    int ret = sched_get_priority_max(policy);
    assert(ret != -1);
    return ret;
}

int get_sched_policy_prior_min(const int policy)
{
    int ret = sched_get_priority_min(policy);
    assert(ret != -1);
    return ret;
}

int get_thread_priority(const pthread_attr_t *attr, int *priority)
{
    struct sched_param param;
    int ret = pthread_attr_getschedparam(attr, ¶m);
    assert(ret == 0);
    *priority = param.sched_priority;
    return ret;
}

int set_thread_priority(pthread_attr_t *attr, const int priority)
{
    struct sched_param param;
    param.sched_priority = priority;

    int ret = pthread_attr_setschedparam(attr, ¶m);
    assert(ret == 0);
}

int main(int argc, char const *argv[])
{
    //对线程属性初始化,初始化完成以后,pthread_attr_t结构体的内容就是OS现在线程的默认属性
    pthread_attr_t attr;
    int ret = pthread_attr_init(&attr);
    assert(ret == 0);

    //获得当前调度策略
    int policy = get_thread_sched_policy(&attr);

    //获取当前调度策略的线程优先级范围

    printf("max priority: %d\n", get_sched_policy_prior_max(policy));
    printf("min priority: %d\n", get_sched_policy_prior_min(policy));

    //获取SCHED_FIFO策略的线程优先级范围
    policy = SCHED_FIFO;
    printf("max priority: %d\n", get_sched_policy_prior_max(policy));
    printf("min priority: %d\n", get_sched_policy_prior_min(policy));

    //获取SCHED_RR策略的线程优先级范围
    policy = SCHED_RR;
    printf("max priority: %d\n", get_sched_policy_prior_max(policy));
    printf("min priority: %d\n", get_sched_policy_prior_min(policy));

    //手动设置调度策略
    set_thread_sched_policy(&attr, SCHED_FIFO);

    //设置优先级
    set_thread_priority(&attr, 5);

    //获取优先级
    int priority;
    get_thread_priority(&attr, &priority);
    printf("priority is %d\n", priority);

    //恢复之前的策略

    //反初始化pthread_attr_t 结构,如果pthread_attr_init实现的属性空间是动态分配的,则会释放该空间
    ret = pthread_attr_destroy(&attr);
    assert(ret == 0);

    return 0;
}

输出结果

hany@ubuntu:~/lab$ ./pthread_sched_prior 
sched_policy = SCHED_OTHER
max priority: 0
min priority: 0
max priority: 99
min priority: 1
max priority: 99
min priority: 1
priority is 5

6.扩展接口

//set/get scheduling policy and parameters of a thread
          
       #include 

       int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param);
       int pthread_getschedparam(pthread_t thread, int *restrict policy, struct sched_param *restrict param);

       //Compile and link with -pthread.