Linux:线程优先级设置

目录

  • 一、背景
  • 二、调整普通线程的优先级
    • ==通过系统命令==
    • ==通过Linux C代码==
  • 三、调整实时线程的优先级
    • ==通过系统命令==
    • ==通过Linux C代码==
  • 四、参考资料(建议一定要阅读)

   在操作系统中,线程优先级决定了线程在 CPU 调度时的重要性。较高优先级的线程会在竞争 CPU 资源时被更频繁地调度,以保证其及时响应。

一、背景

  在Linux中,线程是一种轻量级的执行单元,可以在进程内独立运行。线程可以分为普通线程和实时线程,它们之间的区别在于其调度和优先级设置。

  SCHED_OTHER,普通的调度(非实时线程),应用层设置优先级0,调度器总会给此类线程分配一定的CPU资源,只不过是被分配到的频次和时间片长度较少。每1s中实时线程和普通线程的时间比例是95 :5

  普通线程没有固定的响应时间要求,它们的优先级由系统动态调整。Linux使用CFS调度器来管理普通线程。CFS调度器采用一种称为红黑树的数据结构来维护线程的优先级。每个线程都有一个vruntime值,它表示线程在运行队列中消耗的虚拟时间。CFS调度器会根据线程的vruntime值来确定运行的顺序。优先级较高的线程vruntime值较小,因此能够更早地获得CPU的时间片。

  适用场景:实时性要求不高,但要求必须能被执行的线程。

  SCHED_FIFO,抢占式调度(实时线程),实时先行,应用层设置优先级1-99,同一优先级的多个线程中,一旦某个抢占式线程获取CPU,除非被更高优先级线程抢占(比如在非实时线程中创建一个更高优先级的实时线程),或该线程主动让出CPU资源,否则该线程将会一直占用CPU(但总会分配一点资源给SCHED_OTHER非实时线程)。

  适用场景:实时性要求高,不希望被频繁打断的任务。

  SCHED_RR,轮询式调度(实时线程),实时循环,设置优先级1-99,以循环方式运行,每个线程都有一个时间片来执行任务,时间片耗尽后,该线程将被放入队列的末尾,而较低优先级的线程有机会执行。

  适用场景:实时性要求高,允许被频繁打断的任务。

  在Linux中,可以使用sched_setscheduler函数。这个函数允许我们选择普通线程或实时线程。对于普通线程,可以使用nice函数来动态调整优先级。对于实时线程,可以使用sched_setscheduler函数来设置其类型和优先级。
在这里插入图片描述
  关于优先级高低和数值大小的关系,在应用层和内核中二者是相反的。

  设置线程的优先级需要谨慎,因为过高的优先级可能会导致系统资源的过度占用,从而影响其他线程和进程的正常运行。另外,需要注意的是,只有具有足够权限的用户才能设置较高的实时线程优先级。

  总结起来,Linux中的线程分为普通线程和实时线程。普通线程的优先级由系统动态调整,而实时线程的优先级由用户显式设置。通过合理地设置线程的优先级,可以提高系统的性能和响应时间。然而,设置线程的优先级需要慎重考虑,以避免影响其他线程和进程的正常运行。

二、调整普通线程的优先级

通过系统命令

  在 Linux 系统中,普通线程(非实时线程)的优先级可以通过 nicerenice 命令来进行设置。这些命令允许用户在命令行中调整线程的优先级,而无需特权。

  1. nice命令:nice 命令用于启动新的进程并设置其优先级。它在运行指定命令时按照给定的优先级进行调度。较低的优先级对应较高的 nice 值,这意味着 nice 值越高,优先级越低。命令的基本语法如下:

    nice -n <priority> <command>
    

    其中,-n 后面跟着要设置的优先级值(取值范围一般是-20到19),然后是要执行的命令。

    例如,要以较低的优先级(较高的 nice 值)运行一个命令,可以使用如下命令:

    nice -n 10 <command>
    
  2. renice命令:renice 命令用于修改已经运行的进程的优先级。这使得用户可以在进程运行时动态地调整其优先级,而无需停止和重新启动它。命令的基本语法如下:

    renice <priority> -p <PID>
    

    其中,<priority> 是要设置的优先级值,<PID> 是要修改优先级的进程的进程 ID。

    例如,要将进程的优先级调整为较高,可以使用如下命令:

    renice -5 -p 12345
    

    其中 12345 是目标进程的进程 ID。

  通过 nicerenice 命令,用户可以在 Linux 系统中方便地设置普通线程的优先级,以满足对执行顺序的特定要求。这种方式虽然不能达到实时线程调度的级别,但对于一般的任务调度已经足够有效了。

通过Linux C代码

  nice 函数用于调整进程的调度优先级,允许进程降低自身的优先级,从而降低对系统资源的竞争,也可以提高自身优先级来更快地响应。在Linux系统中,nice 函数的作用是通过改变进程的静态优先级值,来影响进程在CPU上的调度顺序。

  下面是nice函数的原型:

#include <unistd.h>int nice(int inc);
  • 参数 inc 是一个整数,表示要增加或减少的进程优先级。这个值的范围通常是 -20 到 19,其中 -20 表示最高优先级,而 19 表示最低优先级。
  • nice 函数的返回值是新的进程优先级。如果调用成功,返回值通常是 0 到 39 之间的数,其中 0 表示最高优先级,而 39 表示最低优先级。如果调用失败,返回值为 -1,并设置全局变量 errno 以指示错误原因。
    在这里插入图片描述
    以下是一些需要注意的事项:
  1. 只有具有 CAP_SYS_NICE 权限(Linux内核中的一种权限,用于控制进程对于设置任意nice值的能力)或者以 root 用户身份运行的进程才能提高进程的调度优先级。通常,普通用户只能降低自己进程的优先级。
  2. nice 函数的参数 inc 只是相对调整,而不是设定一个绝对的优先级值。只能提高或降低一定的优先级,而不能直接将进程的优先级调整到一个特定的值。
#include <stdio.h>
#include <unistd.h>
#include <errno.h>int main() {// 获取当前进程的优先级int currentPriority = nice(0);if (currentPriority == -1) {perror("Failed to get current process priority");return 1;}printf("Current process priority: %d\n", currentPriority);// 增加进程的优先级int newPriority = nice(-5);if (newPriority == -1) {perror("Failed to increase process priority");return 1;}printf("Increased process priority to: %d\n", newPriority);return 0;
}

  在 Linux 系统中,除了 nice 函数之外,还有一个名为 setpriority 的系统调用可用于设置进程的调度优先级。setpriority 函数提供了更灵活的方式来设置进程的优先级,它允许指定进程的进程组ID和用户ID,而不仅仅是当前进程。

下面是 setpriority 函数的原型:

#include <sys/resource.h>int setpriority(int which, id_t who, int priority);
  • which 参数指定了谁的优先级要被改变。它可以是 PRIO_PROCESS(表示改变指定进程的优先级)、PRIO_PGRP(表示改变指定进程组的所有进程的优先级)或者 PRIO_USER(表示改变指定用户的所有进程的优先级)。
  • who 参数是进程、进程组或用户的 ID,用于指定要进行优先级调整的目标。
  • priority 参数是新的进程优先级。其取值范围与 nice 函数相同,通常为 -20 到 19。

下面是 setpriority 函数的一个简单示例:

#include <stdio.h>
#include <sys/resource.h>
#include <unistd.h>
#include <errno>int main() {// 设置当前进程的优先级if (setpriority(PRIO_PROCESS, 0, 10) == -1) {perror("Failed to set process priority");return 1;}printf("Process priority set to 10\n");return 0;
}

  在这个示例中,setpriority 函数被用来将当前进程的优先级设置为 10。这将影响当前进程的调度优先级。setpriority 函数的使用可以让我们更加灵活地控制进程的调度优先级,可以针对不同的进程组或用户进行设置,提供了比 nice 函数更细粒度的控制能力。

三、调整实时线程的优先级

通过系统命令

  chrt 是一个用于改变进程调度策略或优先级的命令行工具。它在 Linux 系统中提供了对实时进程调度的控制。

  chrt 命令的基本语法如下:

chrt [options] priority command

chrt 命令的常用选项包括:

  • -p, --pid:指定要操作的进程ID。

  • -f, --fifo:设置进程的调度策略为 FIFO(先进先出)。

  • -r, --rr:设置进程的调度策略为 Round Robin(循环调度)。

  • -o, --other:设置进程的调度策略为其他进程调度策略。

  • -m, --max:设置进程的优先级为最高优先级。

  • -e, --min:设置进程的优先级为最低优先级。

  • -p, --priority priority:设置进程的静态优先级。
    在这里插入图片描述
    以下是几个使用示例:

  • 将进程的调度策略设置为 FIFO(先进先出):

    chrt -f -p 90 <command>
    
  • 将进程的调度策略设置为 Round Robin(循环调度):

    chrt -r -p 80 <command>
    
  • 将进程的调度策略设置为其他调度策略(如 SCHED_BATCH):

    chrt -o -p 50 <command>
    
  • 将进程的优先级设置为最高优先级:

    chrt -m -p 99 <command>
    
  • 将进程的优先级设置为最低优先级:

    chrt -e -p 0 <command>
    

  在上述示例中,<command> 是要运行的命令或进程。通过使用不同的选项和参数,chrt 命令可以改变进程的调度策略和优先级,从而影响进程在系统中的调度行为。请注意,使用 chrt 命令可能需要 root 权限或 CAP_SYS_NICE 权限。

通过Linux C代码

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sched.h>#define THREAD_PRIORITY 80 // 设置实时线程的优先级void* thread_function(void* arg) {// 实时线程的具体操作// ...return NULL;
}int main() {pthread_t tid;pthread_attr_t attr;struct sched_param sched_param;// 初始化线程属性pthread_attr_init(&attr);// 设置线程为实时线程pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);pthread_attr_setschedpolicy(&attr, SCHED_FIFO);// 设置线程优先级sched_param.sched_priority = THREAD_PRIORITY;pthread_attr_setschedparam(&attr, &sched_param);// 创建实时线程int result = pthread_create(&tid, &attr, thread_function, NULL);if (result != 0) {fprintf(stderr, "Failed to create thread\n");exit(EXIT_FAILURE);}// 等待实时线程结束pthread_join(tid, NULL);// 清理资源pthread_attr_destroy(&attr);return 0;
}

  pthread_attr_setinheritsched函数用于设置线程属性的继承调度策略。具体来说,它可以控制新创建线程是否继承调用线程的调度策略。函数原型如下:

#include <pthread.h>int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit);

attr是一个指向线程属性对象的指针,inherit参数用于设置继承调度策略。inherit可以是以下两个常量之一:

  • PTHREAD_INHERIT_SCHED:新线程将继承创建它的线程的调度策略。
  • PTHREAD_EXPLICIT_SCHED:使用显式调度策略,即通过 pthread_attr_setschedpolicy 设置特定的调度策略。

  默认情况下,线程属性的继承调度策略是 PTHREAD_INHERIT_SCHED,意味着新创建的线程将继承调用线程的调度策略。

下面是一个示例代码,演示如何使用 pthread_attr_setinheritsched 函数来设置线程属性的继承调度策略:

#include <stdio.h>
#include <pthread.h>int main() {pthread_attr_t attr;int ret;int inherit;// 初始化线程属性pthread_attr_init(&attr);// 获取当前线程属性的继承调度策略ret = pthread_attr_getinheritsched(&attr, &inherit);if (ret == 0) {if (inherit == PTHREAD_INHERIT_SCHED) {printf("继承调度策略:PTHREAD_INHERIT_SCHED\n");} else if (inherit == PTHREAD_EXPLICIT_SCHED) {printf("继承调度策略:PTHREAD_EXPLICIT_SCHED\n");} else {printf("未知的继承调度策略\n");}} else {printf("获取线程属性的继承调度策略失败\n");}// 设置线程属性的继承调度策略inherit = PTHREAD_EXPLICIT_SCHED;ret = pthread_attr_setinheritsched(&attr, inherit);if (ret == 0) {printf("成功设置线程属性的继承调度策略\n");} else {printf("设置线程属性的继承调度策略失败\n");}// 销毁线程属性pthread_attr_destroy(&attr);return 0;
}

四、参考资料(建议一定要阅读)

Linux进程/线程的调度机制介绍:详细解析Linux系统中进程/线程的调度优先级规则

Android 查看线程优先级 android线程栈默认大小

本篇博文引用了大牛文章中的一些精华知识,如有侵权,联系删除!欢迎各位在评论区指导交流!!!

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

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

相关文章

服务器被黑了,记录一下

前两天刚开的新的服务&#xff0c;立马被黑&#xff0c;哈哈。有懂这个是什么黑组织吗&#xff0c;哈哈 All your data is backed up. You must pay 0.017 BTC to 1KdmpErgS3isFf8FrLaTfGHLQPKNsv839G In 48 hours, your data will be publicly disclosed and deleted. (more i…

GEE错误——‘xxx‘ did not match any bands.

这里我们在进行影像展示的时候会出现下面的错误,主要的原因是我们虽然进行了波段运算,但是依旧无法加载,主要原因是我们没有将计算过后的波段信息进行添加到我们的一个多波段影像,这里我们首先来看看代码出现的错误提示。当然这里只是给出了主要的问题,其实在进行波段运算…

Visual Basic入门指南(一)

Visual Basic入门指南 Visual Basic是一种由微软公司开发的简单、易学的编程语言。它被广泛应用于Windows应用程序的开发&#xff0c;并且有着强大的可视化编程能力。本文将介绍Visual Basic的基础知识和常用技巧&#xff0c;帮助读者快速入门。 环境准备 随便找一个软件安装…

java在线票务系统(选座)Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java servlet 在线票务系统&#xff08;选座&#xff09;管理系统是一套完善的java web信息管理系统 系统采用serlvetdaobean&#xff08;mvc模式)&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要…

PowerShell Instal 一键部署TeamCity

前言 TeamCity 是一个通用的 CI/CD 软件平台,可实现灵活的工作流程、协作和开发实践。允许在您的 DevOps 流程中成功实现持续集成、持续交付和持续部署。 系统支持 Centos7,8,9/Redhat7,8,9及复刻系列系统支持 Windows 10,11,2012,2016,2019,2022高版本建议使用9系列系统…

从0到1快速入门ETLCloud

一、ETLCloud的介绍 ETL是将业务系统的数据经过抽取&#xff08;Extract&#xff09;、清洗转换&#xff08;Transform&#xff09;之后加载&#xff08;Load&#xff09;到数据仓库的过程&#xff0c;目的是将企业中的分散、凌乱、标准不统一的数据整合到一起&#xff0c;为企…

CentOS7 系统安装

系统下载 官方下载 清华源下载 安装流程 1. 选择安装系统 2. 选择安装语言 3. 设置网络链接 4. 设置静态IP ![img](https://img-blog.csdnimg.cn/img_convert/53bfedd54b838f95bd8bcb2efa232e23.png)设置时区 5. 磁盘设置&#xff0c;无特殊需求默认就好 6. 安装模式选择 7…

Spark应用程序的结构与驱动程序

Apache Spark是一个强大的分布式计算框架&#xff0c;用于处理大规模数据。了解Spark应用程序的结构和驱动程序是构建高效应用的关键。本文将深入探讨Spark应用程序的组成部分&#xff0c;以及如何编写一个Spark驱动程序来处理数据和执行计算。 Spark应用程序的结构 Spark应用…

cleanmymac这个软件怎么样?值不值得下载

cleanmymac是我必装的mac端清理软件&#xff0c;界面简洁好看&#xff0c;完美适配mac系统&#xff0c;文件清理的速度、精度都比较优秀&#xff0c;还是比较不错的呢。cleanmymac作为一款第三方清洁应用程序&#xff0c;具有专业完整的清理功能&#xff0c;包括释放内存、一键…

【Redis交响乐】Redis中的通用命令

文章目录 1. 基本命令 get set2. 全局命令(1)keys(2)exists(3)del(4)expire && ttl面试题: redis中key的过期策略是怎么实现的?定时器的实现原理(1)基于优先级队列/堆(2)基于时间轮实现的定时器 (5) type 我们知道,redis是按照键值对的方式存储数据的. Redis中基本的命…

根据文法求对应的语言

技巧&#xff1a;最后得到的是终结符组成的闭包 例题&#xff1a; 文法G[S]: S-->AB A-->aAb|ab B-->Bc|&#xff0c;求对应的语言 ①S-->(aAb|ab)(Bc|) ②我们可以观察到&#xff0c;无论A-->aAb还是A-->ab&#xff0c;都一定会同时出现ab,…

Java学习——设计模式——结构型模式1

文章目录 结构型模式代理模式适配器模式 结构型模式 结构型模式主要涉及如何组合各种对象以便获得更好、更灵活的结构。虽然面向对象的继承机制提供了最基本的子类扩展父类的功能&#xff0c;但结构型模式不仅仅简单地使用继承&#xff0c;而更多地通过组合与运行期的动态组合来…

NModbus-一个C#的Modbus协议库实现

NModbus-一个基于C#实现的Modbus通信协议库 最近在学习C#的时候&#xff0c;因为之前做过环保设备时使用C做过环保设备采集使用到了Modbus协议&#xff0c;当时看了一下基于C语言开发的libmodbus库。所以特意搜索看了一下C#下有什么Modbus协议库&#xff0c;在Github上面找了一…

SONiC和ONL所依赖的Debian版本说明

Debian 的最新几个版本 下一代 Debian 正式发行版的代号为 trixie — 测试&#xff08;testing&#xff09;版 Debian 12 (bookworm) — 当前的稳定&#xff08;stable&#xff09;版 Debian 11 (bullseye) — 当前的旧的稳定&#xff08;oldstable&#xff09;版 Debian 10&a…

idea配置docker推送本地镜像到远程私有仓库

目录 1&#xff0c;搭建远程Docker 私有仓库 Docker registry 2&#xff0c;Windows10/11系统上安装Docker Desktop 3&#xff0c;idea 配置远程私有仓库地址 4&#xff0c;idea 配置Docker 5&#xff0c;idea在本地构建镜像 6&#xff0c;推送本地Docker镜像到远程 Dock…

线性代数——(期末突击)行列式(上)-行列式计算、行列式的性质

目录 行列式 行列式计算 逆序数 行列式的性质 转置 两行&#xff08;列&#xff09;互换 两行&#xff08;列&#xff09;对应相等 提公因子 两行&#xff08;列&#xff09;对应成比例 某行&#xff08;列&#xff09;为零 行列式分裂 行列式变换及三角行列式 行…

基于Freeswitch实现的Volte网视频通知应用

现在运营商的Volte网络已经很好的支持视频通话了&#xff0c;因此在原来的电话语音通知的基础上&#xff0c;可以更进一步实现视频的通知&#xff0c;让用户有更好的体验&#xff0c;本文就从技术角度&#xff0c;基于Freeswitch来实现此类应用&#xff08;本文假设读者已对Fre…

三台CentOS7.6虚拟机搭建Hadoop完全分布式集群(三)

这个是笔者大学时期的大数据课程使用三台CentOS7.6虚拟机搭建完全分布式集群的案例&#xff0c;已成功搭建完全分布式集群&#xff0c;并测试跑实例。 9 安装hbase 温馨提示&#xff1a;安装hbase先在master主节点上配置&#xff0c;然后远程复制到slave01或slave02 &#xf…

6130 树的最长路

思路&#xff1a;树的最长路问题可以通过两次 DFS 求解&#xff0c;具体思路如下&#xff1a; 1.第一次 DFS 求树的直径 以任意一个点为起点进行深度优先遍历&#xff08;DFS&#xff09;&#xff0c;找到与该点距离最远的点 u 。 以 u 为起点进行 DFS &#xff0c;找到与 u 距…

pytest pytest-html优化样式

conftest.py import pytest from pytest_metadata.plugin import metadata_keydef pytest_html_report_title(report):report.title"接口测试报告"def pytest_configure(config):# 获取命令行参数中的测试环境、测试版本、开始时间、测试人员config.stash[metadata_…