task_struct结构体的优先级参数详解:prio、static_prio、normal_prio、rt_priority

task_struct 结构体

在这里插入图片描述

   task_struct 结构体定义了4个关于优先级(prio)的参数,这是由于Linux内核里不止一种调度器导致的。

参数实时调度器进程CFS调度器进程
prio正常情况下,prio等于normal_prio正常情况下,prio等于normal_prio
normal_prio99-rt_prioritystatic_prio
static_prio无意义120+nice值
rt_priority1~99无意义

prio 调度优先级

   进程的动态优先级,是调度器使用的优先级

normal_prio 正常优先级

   normal_prio值是根据调度器类型计算出来的
      对于实时进程:normal_prio = 99 - rt_priority
      对于非实时进程: normal_prio = static_prio
   代码实现如下:

#define MAX_RT_PRIO		100

static inline int __normal_prio(struct task_struct *p)
{
   return p->static_prio;
}

static inline int normal_prio(struct task_struct *p)
{
   int prio;

   if (task_has_dl_policy(p))
   	prio = MAX_DL_PRIO-1;
   else if (task_has_rt_policy(p))
   	prio = MAX_RT_PRIO-1 - p->rt_priority;
   else
   	prio = __normal_prio(p);
   return prio;
}

static_prio 静态优先级

   静态优先级,在进程启动时分配,在被CFS调度的进程中才有意义,用户可以通过修改nice值来修改静态优先级,内核不存储nice值,只会通过NICE_TO_PRIO宏将nice值转换为static_prio。

#define DEFAULT_PRIO 120
#define NICE_TO_PRIO(nice)	((nice) + DEFAULT_PRIO)

rt_priority 实时优先级

   实时优先级,在被实时调度器调度的进程中才会有意义

应用编程修改调度策略

  SCHED_NORMAL( 老版本也称SCHED_OTHER): CFS调度:分时调度 不支持优先级

  SCHED_FIFO: 实时调度策略 先入先调度 优先级 1~99

  SCHED_RR: 实时调度策略 时间片轮转 优先级 1~99

SCHED_NORMAL CFS调度策略

   采用SCHED_NORMAL调度策略调度的进程是交给内核的CFS完全公平调度器调度的,对于应用程序开发者来说,被CFS调度器调度的进程是没有优先级之说的,只能靠修改nice值改变权重来增加或减少被调度的时间。

对于SCHED_NORMAL调度策略的进程,调度器采用其静态优先级作为调度依据,进程在创建时,nice值默认为0,也就是说用户创建一个SCHED_NORMAL调度策略的进程,其调度的动态优先级prio值为120,其值高于实时优先级0~100的范围,所以只要就绪队列里存在一个实时调度进程,都会将其抢占。

SCHED_FIFO 和 SCHED_RR 实时调度策略

   采用SCHED_FIFO 和 SCHED_RR调度策略的进程是交给实时调度器调度的,应用开发者是可以调整其优先级的,范围为1~99,值越大,表示优先级越高。
   但是对于内核调度区来说,进程的优先级是数值越低优先级越高,这就是在上一章节所讲的,此时动态优先级prio = 99 - rt_priority,用户不能直接修改prio参数,只能设置的优先级是rt_priority参数。

相关的系统调用

获取优先级范围

sched_get_priority_min(int policy) 获取优先级最小值
sched_get_priority_max(int policy) 获取优先级最大值
policy传参

  获取优先级最大值和最小值后,在设置线程的优先级时,我们就不会设置超出范围的优先级值。

  直接写代码验证一下

#include<stdio.h>
#include <pthread.h>
#include <sched.h>
#include <assert.h>

static void show_thread_priority(int policy)
{
	int prioritymin = sched_get_priority_min(policy);
	int prioritymax = sched_get_priority_max(policy);
	
	assert(prioritymin != -1);
	assert(prioritymax != -1);	
	
	printf("priority %d ~ %d\n",prioritymin,prioritymax);
}

int main(int argc,char* argv[])
{
	printf("------- SCHED_FIFO priority-------\n");
	show_thread_priority(SCHED_FIFO);
	printf("------- SCHED_RR priority-------\n");
	show_thread_priority(SCHED_RR);
	printf("------- SCHED_OTHER priority-------\n");	
	show_thread_priority(SCHED_OTHER);	
	
	return 0;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sDgytHEH-1632535885317)(en-resource://database/16884:1)]
  从以上代码的运行结果,可以看出SCHED_FIFO和SCHED_RR调度策略可以使用的优先级范围为199,而SCHED_OTHER调度策略的优先级范围为00,也就是不支持优先级使用。

修改线程的调度策略

int pthread_attr_setschedpolicy(pthread_attr_t *attr,int policy)
int pthread_attr_getschedpolicy(pthread_attr_t attr,int policy)
#include<stdio.h>
#include <pthread.h>
#include <sched.h>
#include <assert.h>

//获取线程的调度策略
static int get_thread_policy(pthread_attr_t *attr)
{
   int plicy;
   int rs=pthread_attr_getschedpolicy(attr,&plicy);

   assert(rs==0); 

   switch(plicy)
   {
       case SCHED_FIFO:
       printf("policy=SCHED_FIFO.\n");
       break;

       case SCHED_RR:
       printf("policy=SCHED_RR.\n");
       break;

       case SCHED_OTHER:
       printf("policy=SCHED_OTHER.\n");
       break;

       default:
       printf("policy=UNKNOWN.\n");
       break;
   }

   return plicy;
}

//改变线程的调度策略
static void set_thread_policy(pthread_attr_t *attr,int policy)
{
   int ret = pthread_attr_setschedpolicy(attr,policy);
   
   assert(ret == 0);
   
}


int main(int argc,char* argv[])
{
   pthread_attr_t attr;

   int rs=pthread_attr_init(&attr);
   assert(0==rs);
   
   printf("------- Set Policy to SCHED_FIFO -------\n");
   set_thread_policy(&attr,SCHED_FIFO);
   get_thread_policy(&attr);
   printf("------- Set Policy to SCHED_RR -------\n");
   set_thread_policy(&attr,SCHED_RR);
   get_thread_policy(&attr);
   printf("------- Set Policy to SCHED_OTHER -------\n");
   set_thread_policy(&attr,SCHED_OTHER);	
   get_thread_policy(&attr);
   
   return 0;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IAFL0u77-1632535886012)(en-resource://database/16886:1)]

设置和获取线程的优先级

int pthread_attr_setschedparam(pthread_attr_t* attr_t,const)
int pthread_attr_getschedparam(pthread_attr_t* attr_t,const)
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明故宫的记忆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值