Linux:线程优先级设置

news2024/9/23 7:32:08

目录

  • 一、背景
  • 二、调整普通线程的优先级
    • ==通过系统命令==
    • ==通过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.coloradmin.cn/o/1335528.html

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

相关文章

Python能做大项目(6)Poetry -- 项目管理的诗和远方之一

[Poetry] 是一个依赖管理和打包工具。Poetry 的作者解释开发 Poetry 的初衷时说&#xff1a; 通过前面的案例&#xff0c;我们已经提出了一些问题。但不止于此。 当您将依赖加入到 requirements.txt 时&#xff0c;没有人帮你确定它是否与既存的依赖能够和平共处&#xff0c;这…

java数据结构与算法刷题-----LeetCode633. 平方数之和

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 思路一&#xff1a;双指针 可以使用双指针&#xff0c;不断从两个方向匹配…

分享71个Java源码总有一个是你想要的

分享71个Java源码总有一个是你想要的 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/1frK-W3GT8WrydSlQ-E3o6A?pwd6666 提取码&#xff1a;6666 UI代码 def __init__(self):import …

大数据技术学习笔记(十一)—— Flume

目录 1 Flume 概述1.1 Flume 定义1.2 Flume 基础架构 2 Flume 安装3 Flume 入门案例3.1 监控端口数据3.2 实时监控单个追加文件3.3 实时监控目录下多个新文件3.4 实时监控目录下的多个追加文件 4 Flume 进阶4.1 Flume 事务4.2 Flume Agent 内部原理4.3 Flume 拓扑结构4.3.1 简单…

C++之多层 if-else-if 结构优化(三)

C之多层 if-else-if 结构优化(二)-CSDN博客 接上面的内容继续讲解多层 if-else-if结构优化 8、利用规则执行器来进行优化 8.1 业务场景介绍 if (未注册用户){return false; }if (是否国外用户) {return false; }if (刷单用户) {return false; }if (未付费用户 && 不…

数据仓库【2】:架构

数据仓库【2】&#xff1a;架构 1、架构图2、ETL流程2.1、ETL -- Extract-Transform-Load2.1.1、数据抽取&#xff08;Extraction&#xff09;2.1.2、数据转换&#xff08;Transformation&#xff09;2.1.3、数据加载&#xff08; Loading &#xff09; 2.2、ETL工具2.2.1、结构…

github新建仓库推送代码教学

之前一直用gitee&#xff0c;准备转到github。因为一步一步尝试。如果是新手或许文章会有帮助 点击 new 创建 拉代码 Idea 打开 复制一个 pom 文件作为 maven 管理 提交代码 不出意外的出意外&#xff0c;报错 点击authorize JetBrains 失败 分析问题 本质就是没有…

零基础入门网络安全必看的5本书籍(附PDF)

书中自有黄金屋&#xff0c;书中自有颜如玉。很多人学习一门技术都会看大量的书籍&#xff0c;经常也有朋友询问&#xff1a;零基础刚入门&#xff0c;应该看哪些书&#xff1f;应该怎么学&#xff1f;等等问题。今天就整理了5本零基础入门网络安全必看书籍&#xff0c;希望能帮…

Ubuntu 22.04.3 Server 设置静态IP 通过修改yaml配置文件方法

目录 1.查看网卡信息 2.修改yaml配置文件 3.应用新的网络配置 4.重新启动网络服务 文章内容 本文介绍Ubuntu 22.04.3 Server系统通过修改yaml配置文件配置静态 ip 的方法。 1.查看网卡信息 使用ifconfig命令查看网卡信息获取网卡名称​ 如果出现Command ifconfig not fo…

若依SQL Server开发使用教程

1. sys_menu表中的将菜单ID修改为自动ID,解决不能增加菜单的问题&#xff0c;操作流程如下&#xff1a; 解决方案如下 菜单栏->工具->选项 点击设计器&#xff0c;去掉阻止保存要求更新创建表的更改选项&#xff0c;点确认既可以保存了 2 自动生成代码找不表的解决方案…

智能优化算法应用:基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.指数分布算法4.实验参数设定5.算法结果6.…

20231225使用BLE-AnalyzerPro WCH升级版BLE-PRO蓝牙分析仪抓取BLE广播数据

20231225使用BLE-AnalyzerPro WCH升级版BLE-PRO蓝牙分析仪抓取BLE广播数据 2023/12/25 20:05 结论&#xff1a;硬件蓝牙分析仪 不一定比 手机端的APK的效果好&#xff01; 亿佰特E104-2G4U04A需要3片【单通道】&#xff0c;电脑端的UI为全英文的。 BLE-AnalyzerPro WCH升级版B…

前端---css 的介绍

1. css 的定义 css(Cascading Style Sheet)层叠样式表&#xff0c;它是用来美化页面的一种语言。 没有使用css的效果图 使用css的效果图 2. css 的作用 美化界面, 比如: 设置标签文字大小、颜色、字体加粗等样式。控制页面布局, 比如: 设置浮动、定位等样式。 3. css 的基本语…

B/S和C/S的区别和联系

B/S和C/S的区别和联系 1 B/S2 C/S3 B/S和C/S区别4 B/S和C/S联系 1 B/S B/S&#xff08;Brower/Server&#xff09;架构&#xff0c;也称为B/S结构或B/S模式&#xff0c;是Web兴起后的一种网络结构模式。在这种模式下&#xff0c;Web浏览器成为客户端最主要的软件。系统功能实现…

MongoDB文档操作

3.3 文档操作 3.1 文档介绍 文档的数据结构和 JSON 基本一样。 所有存储在集合中的数据都是 BSON 格式。 BSON 是一种类似 JSON 的二进制形式的存储格式&#xff0c;是 Binary JSON 的简称。 文档是一组键值(key-value)对(即 BSON)&#xff0c;一个简单的文档例子如下&…

AI 引擎系列 8 - 运行时比率参数简介

简介 在 Versal AI 引擎 2 一文 中&#xff0c;我们注意到计算图 (graph) 文件中有一行内容用于为每个内核实例定义运行时比率参数。 在本文中&#xff0c;我们将讲解该参数如何影响 AI 引擎应用的资源使用率和性能。 要求 下文要求您通读前几篇 AI 引擎系列博文。 AI 引擎系…

低代码实施复杂应用的实践方法

内容来自演讲&#xff1a;韦有炬 | 柳州知行远企业管理咨询有限公司 | 总经理 摘要 本文探讨了在全民开发时代如何使用低代码实施复杂应用并降低上线风险。文章分析了复杂系统实施失败的风险&#xff0c;包括项目规划不周、人员变动、企业基础管理不足等&#xff0c;并对比了低…

基于JavaServelet的同学录管理系统(Java毕业设计)

点击咨询源码 大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的…

智能优化算法应用:基于卷积优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于卷积优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于卷积优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.卷积优化算法4.实验参数设定5.算法结果6.…

搭建react+ant design pro+umi 项目框架

一、 写本文的原因 我搭建reactantdumi这个框架的原始资料主要是来源于&#xff08;ReactUmi4从零快速搭建中后台系统保姆级记录教程&#xff08;一、项目创建及初始化&#xff09;&#xff09; 而我写这篇文章的本意就是用来记录我用搭建时候的步骤汇总。 二、 npm和node版…