Linux 线程优先级

news2025/7/21 5:17:45

目录标题

  • 概述
  • Linux进程调度的三种策略
  • Linux 线程优先级
    • 对于实时任务
    • 对于普通任务
    • top中的PR和NI
    • 其他说明
  • 代码示例
    • 设置为实时进程
    • 优先级测试代码


概述

概述内容


常见的运用场景

  • 1
  • 2;
  • 3;

Linux进程调度的三种策略

  • SCHED_OTHER,分时调度策略
    该策略是是默认的Linux分时调度(time-sharing scheduling)策略,它是Linux线程默认的调度策略。SCHED_OTHER策略的静态优先级总是为0,对于该策略列表上的线程,调度器是基于动态优先级(dynamic priority)来调度的,动态优先级是跟nice中相关(nice值可以由接口nice, setpriority,sched_setattr来设置),该值会随着线程的运行时间而动态改变,以确保所有具有SCHED_OTHER策略的线程公平运行
  • SCHED_FIFO,实时调度策略,先到先服务。
    根据进程的优先级进行调度,一旦抢占到 CPU 则一直运行,直达自己主动放弃或被被更高优先级的进程抢占;
  • SCHED_RR,实时调度策略,时间片轮转
    在 SCHED_FIFO 的基础上,加上了时间片的概念。当一个进程抢占到 CPU 之后,运行到一定的时间后,调度器会把这个进程放在 CPU 中,当前优先级进程队列的末尾,然后选择另一个相同优先级的进程来执行;

Linux 线程优先级

进程调度策略优先级说明
普通进程SCHED_OTHER或SCHED_NORMAL100-139这个区间的优先级又称为静态优先级,不会随着时间而改变,内核不会修改它,只能通过系统调用nice去修改,静态优先级数值越大,进程的优先级越小,分配的基时间量就越少。普通进程几乎是无法分到时间片的(只能分到5%的CPU时间)。static priority=nice+20+MAX_RT_PRIO,nice值[-20,19],MAX_RT_PRIO默认为100,这样做的好处是,任何内核态进程优先级都大于用户态的进程.
实时进程SCHED_FIFO或SCHED_RR0-99只有在下述事件之一发生时,实时进程才会被另外一个进程取代 1. 进程被另外一个具有更高实时优先级的实时进程抢占2. 进程执行了阻塞操作并进入睡眠3. 进程停止(处于TASK_STOPPED 或TASK_TRACED状态)或被杀死4. 进程通过调用系统调用sched_yield(),自愿放弃CPU5. 进程基于时间片轮转的实时进程(SCHED_RR),而且用完了它的时间片.

在这里插入图片描述

这张图表示的是内核中的优先级,分为两段。
前面的数值 0-99 是实时任务,后面的数值 100-139 是普通任务。
数值越低,代表这个任务的优先级越高。
以上是从内核角度来看的优先级。


我们在应用层创建线程的时候,设置了一个优先级数值,这是从应用层角度来看的优先级数值。
但是内核并不会直接使用应用层设置的这个数值,而是经过了一定的运算,才得到内核中所使用的优先级数值(0 ~ 139)。

对于实时任务

我们在创建线程的时候,可以通过下面这样的方式设置优先级数值(0 ~ 99):

struct sched_param param;
param.__sched_priority = xxx;

当创建线程函数进入内核层面的时候,内核通过下面这个公式来计算真正的优先级数值:
kernel priority = 100 - 1 - param.__sched_priority

如果应用层传入数值 0,那么在内核中优先级数值就是 99(100 - 1 - 0 = 99),在所有实时任务中,它的优先级是最低的。
如果应用层传输数值 99,那么在内核中优先级数值就是 0(100 - 1 - 99 = 0),在所有实时任务中,它的优先级是最高的。
因此,从应用层的角度看,传输人优先级数值越大,线程的优先级就越高;数值越小,优先级就越低。
与内核角度是完全相反的!

对于普通任务

调整普通任务的优先级,是通过 nice 值来实现的,内核中也有一个公式来把应用层传入的 nice 值,转成内核角度的优先级数值:
kernel prifoity = 100 + 20 + nice
nice 的合法数值是:-20 ~ 19
如果应用层设置线程 nice 数值为 -20,那么在内核中优先级数值就是 100(100 + 20 + (-20) = 100),在所有的普通任务中,它的优先级是最高的。
如果应用层设置线程 nice 数值为 19,那么在内核中优先级数值就是 139(100 +20 +19 = 139),在所有的普通任务中,它的优先级是最低的。
因此,从应用层的角度看,传输人优先级数值越小,线程的优先级就越高;数值越大,优先级就越低。
与内核角度是完全相同的!

top中的PR和NI

top命令中pri的计算方法说明
普通进程top_pr=static_priority-100static_priority取值是[100,139],所以top_pri取值是[0,39]
实时进程top_pri=-1-real_time_prioritychrt命令就是修改实时进程的优先级,比如给进程12345分配优先级为93,chrt -p 93 12345,则top命令pri值显示的是-94。有的实时进程的pri值显示的是rt,没有具体显示数值

其他说明

对于多核处理器,分布不同核时,调度策略、优先级,都不起作用!(准确的说:调度策略和优先级,在线程所在的那个 CPU 中是起作用的)

代码示例

设置为实时进程

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <pthread.h>
 4 #include <sched.h>
 5 
 6 
 7 pid_t pid = getpid();
 8 struct sched_param param;
 9 param.sched_priority = sched_get_priority_max(SCHED_FIFO);   // 也可用SCHED_RR
10 sched_setscheduler(pid, SCHED_RR, &param);                   // 设置当前进程
11 pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);   // 设置当前线程

优先级测试代码

#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <assert.h>
 
static int get_thread_policy(pthread_attr_t *attr)
{
	int policy;
	int rs = pthread_attr_getschedpolicy(attr,&policy);
	assert(rs==0);
 
switch(policy)
{
	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 policy;
}
 
static void show_thread_priority(pthread_attr_t *attr,int policy)
{
	int priority = sched_get_priority_max(policy);
	assert(priority != -1);
	printf("max_priority=%d\n",priority);
	 
	priority= sched_get_priority_min(policy);
	assert(priority != -1);
	printf("min_priority=%d\n",priority);
}
 
static int get_thread_priority(pthread_attr_t *attr)
{
	struct sched_param param;
	int rs = pthread_attr_getschedparam(attr,¶m);
	assert(rs == 0);
	 
	printf("priority=%d\n",param.__sched_priority);
	return param.__sched_priority;
}
 
static void set_thread_policy(pthread_attr_t *attr,int policy)
{
	int rs = pthread_attr_setschedpolicy(attr,policy);
	assert(rs==0);
}
 
int main(void)
{
	pthread_attr_t attr;
	int rs;
	 
	rs = pthread_attr_init(&attr);
	assert(rs==0);
	 
	int policy = get_thread_policy(&attr);
	 
	printf("Show current configuration of priority\n");
	get_thread_policy(&attr);
	show_thread_priority(&attr,policy);
	 
	printf("show SCHED_FIFO of priority\n");
	show_thread_priority(&attr,SCHED_FIFO);
	 
	printf("show SCHED_RR of priority\n");
	show_thread_priority(&attr,SCHED_RR);
	 
	printf("show priority of current thread\n");
	get_thread_priority(&attr);
	 
	printf("Set thread policy\n");
	 
	printf("set SCHED_FIFO policy\n");
	set_thread_policy(&attr,SCHED_FIFO);
	get_thread_policy(&attr);
	get_thread_priority(&attr);
	 
	printf("set SCHED_RR policy\n");
	set_thread_policy(&attr,SCHED_RR);
	get_thread_policy(&attr);
	 
	printf("Restore current policy\n");
	set_thread_policy(&attr,policy);
	get_thread_priority(&attr);
	 
	rs = pthread_attr_destroy(&attr);
	assert(rs==0);
	 
	return 0;
} 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/368617.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【读论文】AttentionFGAN

【读论文】AttentionFGAN介绍网络架构提取红外图像目标信息的网络辨别器损失函数生成器损失函数辨别器损失函数总结参考论文&#xff1a; https://ieeexplore.ieee.org/document/9103116/如有侵权请联系博主介绍 好久没有读过使用GAN来实现图像融合的论文了&#xff0c;正好看…

【Java面试八股文宝典之基础篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day14

大家好&#xff0c;我是陶然同学&#xff0c;软件工程大三今年实习。认识我的朋友们知道&#xff0c;我是科班出身&#xff0c;学的还行&#xff0c;但是对面试掌握不够&#xff0c;所以我将用这100多天更新Java面试题&#x1f643;&#x1f643;。 不敢苟同&#xff0c;相信大…

计算机专业要考什么证书?

大家好&#xff0c;我是良许。 从去年 12 月开始&#xff0c;我已经在视频号、抖音等主流视频平台上连续更新视频到现在&#xff0c;并得到了不错的评价。 视频 100% 原创录制&#xff0c;绝非垃圾搬运号&#xff0c;每个视频都花了很多时间精力用心制作&#xff0c;欢迎大家…

Android高仿陌陌应用点点滑动效果

效果图&#xff1a;分析:从效果上看图片的展示具有层次感&#xff0c;在数据结构上更像是stack,所以通过继承FrameLayout来实现&#xff08;不清楚FrameLayout布局特点的可以先百度下哈&#xff09;&#xff0c;外面是通过继承FrameLayout自定义的TinderStackLayout&#xff0c…

SpringBoot-基础篇

SpringBoot基础篇 ​ 在基础篇中&#xff0c;我给学习者的定位是先上手&#xff0c;能够使用SpringBoot搭建基于SpringBoot的web项目开发&#xff0c;所以内容设置较少&#xff0c;主要包含如下内容&#xff1a; SpringBoot快速入门SpringBoot基础配置基于SpringBoot整合SSMP…

为你的Vue2.x老项目安装Vite发动机吧

天下苦webpack久矣&#xff0c;相信作为前端开发者一定经历过在项目迭代时间较长的时候经历漫长等待的这一过程&#xff0c;每一次保存都会浪费掉大量时间&#xff0c;这是webpack这种机制所带来的问题。 于是&#xff0c;尤大为我们带来了新一代前端构建工具&#xff1a;vite…

搜索旋转排序数组、路径总和 II、拆分数字

文章目录搜索旋转排序数组&#xff08;数组、二分查找&#xff09;路径总和 II&#xff08;树、深度优先搜索&#xff09;拆分数字&#xff08;算法&#xff09;搜索旋转排序数组&#xff08;数组、二分查找&#xff09; 整数数组 nums 按升序排列&#xff0c;数组中的值 互不…

Transformer学习笔记

Transformer学习笔记1. 参考2. 模型图3.encoder部分3.1 Positional Encoding3.2 Muti-Head Attention3.3 ADD--残差连接3.4 Norm标准化3.5 单个Transformer Encoder流程图4.decoder部分4.1 mask Muti-Head Attention4.2 Muti-Head Attention5 多个Transformer Encoder和多个Tra…

详解数据库基本概念

数据库&#xff08;DataBase 简称 DB&#xff09;&#xff1a;是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合数据库管理系统&#xff08;DataBase Management System 简称 DBMS&#xff09;&#xff1a;是一种操纵和管理数据库的大型软件&#xf…

基于嵌入式linux的DHCP服务器的搭建与移植(udhcp)

DHCP是Dynamic Host Configuration Protocol的缩写&#xff0c;即动态主机配置协议。DHCP是一个很重要的局域网的网络协议&#xff0c;使用UDP协议实现动态配置功能&#xff0c;主要有以下用途&#xff1a; 1、为内部网络或网络服务供应商自动分配IP地址&#xff1b; 2、为用…

利用Python和Sprak求曲线与X轴上方的面积

有n组标本(1, 2, 3, 4), 每组由m个( , , ...)元素( , )组成(m值不定), . 各组样本的分布 曲线如下图所示. 通过程序近似实现各曲线与oc, cd直线围成的⾯积. 思路 可以将图像分成若干个梯形&#xff0c;每个梯形的底边长为(Xn1 - Xn-1)&#xff0c;面积为矩形的一半&#xff0c…

原创壁纸小程序独立后台(1.3.5版本介绍)

1、新版本开发目的 历经前两次版本迭代&#xff0c;本人发现在整个系统的架构方面存在一定的缺陷&#xff0c;这种缺陷就是前后端不分离&#xff0c;导致在后期的维护方面遇到了很多问题。 那么这次版本更新并没有带来很多新的功能&#xff0c;而是重构了系统并优化UI&#x…

【PyQt5图形界面编程(2)】:创建工程

创建工程 一、创建工程二、开始开发1、运行Qt5Designer,创建QT窗口2、运行pyUIC,转换xx.ui成xx.py3、main.py中引用xx.py中的类4、打包main.py成main.exe来发布5、执行终端报警处理方法三、其他(如果涉及)1、配置环境变量一、创建工程 采用虚拟环境来创建工程 相关的paka…

STM32FreeRTOS - 按键实现任务挂起和恢复

STM32f103C8T6 FreeRTOS - 按键实现任务挂起和恢复&#xff0c;按键按下时&#xff0c;LED任务执行&#xff0c;led闪烁&#xff0c;当led任务挂起&#xff0c;Led停止闪烁。1.STM32CubeMX 创建任务1.1配置GPIO按键配置外部中断触发GPIO绿灯&#xff0c;红灯配置输出模式1.2配置…

Android中级——色彩处理和图像处理

色彩处理 通过色彩矩阵处理 色彩矩阵介绍 图像的RGBA可拆分为一个4行5列的矩阵和5行1列矩阵相乘 其中4行5列矩阵即为ColorMatrix&#xff0c;可通过调整ColorMatrix间接调整RGBA 第一行 abcde 决定新的 R第二行 fghij 决定新的 G第三行 klmno 决定新的 G第四行 pqrst 决定新…

Ubuntu64位下安装Anaconda3的详细过程

Ubuntu下安装Anaconda的详细过程 下载 Anaconda&#xff1a;首先&#xff0c;您需要在 Anaconda 的官网上下载适合您的 Linux 版本的安装包。您可以使用以下命令下载最新版本&#xff1a; wget https://repo.anaconda.com/archive/Anaconda3-2021.05-Linux-x86_64.sh下载完毕后…

春季 3 月 · CSM 认证周末班【提前报名特惠】“全球金牌课程”CST 导师亲授

为什么“模块化分时段”单元教学 ☆ 有脑科学研究资料揭示: 成人学习者持续 3.5 小时已经达到极限&#xff0c;新模式教学&#xff0c;给学习者留有一些时间和空间去消化吸收&#xff0c;反思回顾(Reflection)&#xff0c;讲师布置一些小作业&#xff0c;让学员课后去练习&…

React Draggable 实现图片拖拽

React Draggable 实现拖拽 React Draggable 是 react 生态中&#xff0c;最好用的拖拽实现库之一。如果你的应用中需要实现拖拽功能&#xff0c;可以尝试用 react-draggable&#xff0c;它可以满足多数情况下的拖拽需求&#xff0c;比如一个弹出设置浮窗&#xff0c;可以相互遮…

2月更新!EasyOps又迎来新升级,解锁9大新特性

又到了每月产品盘点时刻&#xff0c;9大新功能上线和升级优化&#xff0c;涉及Hyperlnsight超融合持续观测平台、CMDB立体化资源管理平台、DevOps持续交付平台、AutoOps自动化运维平台、EasyHub资源共享平台&#xff0c;在不断的技术创新过程中&#xff0c;进一步加速IT运维效率…

Android framework socketpair

简述 在Linux中&#xff0c;socketpair函数可以用于创建一对相互连接的、通信域为AF_UNIX的套接字&#xff0c;其中一个套接字可用于读取&#xff0c;另一个套接字可用于写入。可以使用这对套接字在同一进程内进行进程间通信&#xff08;IPC&#xff09;。 以下是使用socketp…