关于linux下进程和线程优先级的一些总结

2023-05-16

1.进程

1.1 基础

进程优先级值越小,优先级越大,进程的优先级是PRI值不是Nice值,普通进程优先级可以通过Nice值调整,实时进程不行

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(),自愿放弃CPU
5. 进程基于时间片轮转的实时进程(SCHED_RR),而且用完了它的时间片
SCHED_RR同优先级的实时进程中,每个进程又是通过获得时间片来分时运行。,
不同优先级的实时进程,高优先级的实时进程能够抢占低优先级的实时进程
SCHED_FIFO同优先级的实时进程,后进入的进程要等前一个进程释放了CPU,才能够运行(没有时间片)。
不同优先级的实时进程,高优先级的实时进程能够抢占低优先级的实时进程。

1.2 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,没有具体显示数值

1.3 chrt命令

chrt可以修改实时进程的调度策略和优先级
在这里插入图片描述
chrt -p -f 10 1234 # 修改调度策略为 SCHED_FIFO, 并且优先级为10

1.4 taskset命令

参考链接

# 命令行形式
taskset [options] mask command [arg]...
taskset [options] -p [mask] pid
PARAMETER    
mask : cpu亲和性,当没有-c选项时, 其值前无论有没有0x标记都是16进制的,当有-c选项时,其值是十进制的.    
command : 命令或者可执行程序    
arg : command的参数    
pid : 进程ID,可以通过ps/top/pidof等命令获取

OPTIONS    
	   -a, --all-tasks (旧版本中没有这个选项)
	  		 这个选项涉及到了linux中TID的概念,他会将一个进程中所有的TID都执行一次CPU亲和性设置.
	  		 TID就是Thread ID,他和POSIX中pthread_t表示的线程ID完全不是同一个东西.        
	  		 Linux中的POSIX线程库实现的线程其实也是一个进程(LWP),这个TID就是这个线程的真实PID.
       -p, --pid
              操作已存在的PID,而不是加载一个新的程序
       -c, --cpu-list
              声明CPU的亲和力使用数字表示而不是用位掩码表示. 例如 0,5,7,9-11.
       -h, --help
              display usage information and exit
       -V, --version
              output version information and exit  
USAGE    
		1) 使用指定的CPU亲和性运行一个新程序      
		taskset [-c] mask command [arg]...        
			举例:使用CPU0运行ls命令显示/etc/init.d下的所有内容          
			 taskset -c 0 ls -al /etc/init.d/    
		2) 显示已经运行的进程的CPU亲和性      
			taskset -p pid        
				举例:查看init进程(PID=1)的CPU亲和性          
					taskset -p 1    
		3) 改变已经运行进程的CPU亲和力        
			taskset -p[c] mask pid        
				举例:打开2个终端,在第一个终端运行top命令,第二个终端中          
					首先运行:[~]# ps -eo pid,args,psr | grep top #获取top命令的pid和其所运行的CPU号          
					其次运行:[~]# taskset -cp 新的CPU号 pid       #更改top命令运行的CPU号          
					最后运行:[~]# ps -eo pid,args,psr | grep top #查看是否更改成功  
PERMISSIONS        
			一个用户要设定一个进程的CPU亲和性,如果目标进程是该用户的,则可以设置,如果是其他用户的,则会设置失败,提示 Operation not permitted.当然root用户没有任何限制.        
			任何用户都可以获取任意一个进程的CPU亲和性.

2. 线程

2.1 基础

  线程的优先级跟进程差不多,进程是在系统中竞争cpu资源,线程是在当前进程中竞争cpu资源(可以通过设置作用域竞争系统资源)。

2.2 linux线程优先级设置

2.2.1 得到线程可设置的最大最低优先级

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

SCHED_OTHER 是不支持优先级使用的,它最大和最小优先级都是0。
SCHED_FIFO 和 SCHED_RR 支持优先级的使用,他们分别为1和99,数值越大优先级越高

2.2.2 设置和获取优先级

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);

例如:
sched_param     Param;
param.sched_priority = 51; //设置优先级

2.2.3 改变线程调度策略

系统创建的线程默认是SCHED_OTHER

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);

例如:
pthread_attr_t  Attr;
pthread_attr_init(&Attr);
pthread_attr_setschedpolicy(&Attr,SCHED_FIFO);

2.2.4 线程分离状态

  分离状态决定一个线程以什么样的方式来终止自己
  当用pthread_create创建一个线程时,默认的是非分离状态,只有当pthread_join()函数等待线程返回时,才会释放线程资源。
  如果是分离状态,不用调用pthread_join(),当线程结束退出时会自动释放资源。

#include <pthread.h>
 
int pthread_attr_getdetachstate(const pthread_attr_t * attr, int * detachstate);
int pthread_attr_setdetachstate(pthread_attr_t * attr, int detachstate);
 
 
/********************************
参数:attr:线程属性变量
      detachstate:分离状态属性   
若成功返回0,若失败返回-1。
           
设置的时候可以有两种选择:
<1>.detachstate参数为:PTHREAD_CREATE_DETACHED     分离状态启动
<2>.detachstate参数为:PTHREAD_CREATE_JOINABLE     正常启动线程
*************************************/
也可以在创建线程后,在线程函数内调用pthread_detach(pthread_self())来设置线程分离状态

2.2.5 线程的继承性

 #include <pthread.h>
 
int pthread_attr_getinheritsched(const pthread_attr_t *attr,int *inheritsched);
int pthread_attr_setinheritsched(pthread_attr_t *attr,int inheritsched);
 
/******************************
参数:
attr                线程属性变量
inheritsched     线程的继承性
	PTHREAD_INHERIT_SCHED: 新的线程继承创建线程的策略和参数!
	PTHREAD_EXPLICIT_SCHED:新的线程继承策略和参数来自于schedpolicy和schedparam属性中显式设置的调度信息!
若成功返回0,若失败返回-1。
*******************************/          

2.2.6 线程的作用域

#include <pthread.h>   
int    pthread_attr_getscope( const pthread_attr_t * attr, int * scope );
int    pthread_attr_setscope( pthread_attr_t*, int scope );

/*************************************
作用域控制线程是否在进程内或在系统级上竞争资源,可能的值是
PTHREAD_SCOPE_PROCESS(进程内竞争资源)
PTHREAD_SCOPE_SYSTEM   (系统级竞争资源)。
/**************************************
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于linux下进程和线程优先级的一些总结 的相关文章

  • ioctl 命令的用户权限检查

    我正在实现 char 驱动程序 Linux 并且我的驱动程序中有某些 IOCTL 命令仅需要由 ADMIN 执行 我的问题是如何在 ioctl 命令实现下检查用户权限并限制非特权用户访问 IOCTL 您可以使用bool capable in
  • 执行命令而不将其保留在历史记录中[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 在进行软件开发时 经常需要在命令行命令中包含机密信息 典型示例是将项目部署到服务器的凭据设置为环境变量 当我不想将某些命令存储在命令历史记
  • 在 .gitconfig 中隐藏 GitHub 令牌

    我想将所有点文件存储在 GitHub 上 包括 gitconfig 这需要我将 GitHub 令牌隐藏在 gitconfig 中 为此 我有一个 gitconfig hidden token 文件 这是我打算编辑并放在隐藏令牌的 git 下
  • 通过 Visual Studio 2017 使用远程调试时 Linux 控制台输出在哪里?

    我的Visual Studio 2017 VS2017 成功连接Linux系统 代码如下 include
  • 如何使用 Cloud Init 挂载未格式化的 EBS 卷

    Context 我正在使用https wiki jenkins io display JENKINS Amazon EC2 Plugin https wiki jenkins io display JENKINS Amazon EC2 Pl
  • 在centos中安装sqlite3 dev和其他包

    我正在尝试使用 cpanel 在 centos 机器上安装 sqlite dev 和其他库 以便能够编译应用程序 我对 debian 比 centos 更熟悉 我知道我需要的库是 libsqlite3 dev libkrb5 dev lib
  • 使用非规范地址检索内存数据会导致 SIGSEGV 而不是 SIGBUS

    我无法使用以下汇编代码产生 总线错误 这里我使用的内存地址不是合法的 规范地址 那么 我怎样才能触发该错误呢 我在带有 NASM 2 14 02 的 Ubuntu 20 04 LTS 下运行这段代码 但它会导致负载出现 SIGSEGV 分段
  • 使用循环在 C 中管道传输两个或多个 shell 命令

    我正在尝试执行ls wc l通过 C 语言程序 而不是使用命令行 这是我当前的工作代码 int main int pfds 2 pipe pfds pid t pid fork if pid 0 The child process clos
  • 如何获取 (Linux) 机器的 IP 地址?

    这个问题和之前问的几乎一样如何获取本地计算机的IP地址 https stackoverflow com questions 122208 get the ip address of local computer 问题 但是我需要找到一个的I
  • 为什么 fopen("any_path_name",'r') 不给出 NULL 作为返回值?

    在调试一些代码时 我得到如下内容 include
  • 使用 MAX_ORDER / 包含 mmzone.h

    根据https www kernel org doc Documentation networking packet mmap txt https www kernel org doc Documentation networking pa
  • 与 pthread 的进程间互斥

    我想使用一个互斥体 它将用于同步对两个不同进程共享的内存中驻留的某些变量的访问 我怎样才能做到这一点 执行该操作的代码示例将非常感激 以下示例演示了 Pthread 进程间互斥体的创建 使用和销毁 将示例推广到多个进程作为读者的练习 inc
  • 静态方法的 Java 内存模型

    我来自操作系统和 C 语言背景 在代码编译时 世界很简单 需要处理和理解堆栈 堆文本部分等 当我开始学习 Java 时 我确实了解 JVM 和垃圾收集器 我对静态方法感到很有趣 根据我的理解 类的所有实例都会在堆中创建 然后被清理 但是 对
  • 绕过 dev/urandom|random 进行测试

    我想编写一个功能测试用例 用已知的随机数值来测试程序 我已经在单元测试期间用模拟对其进行了测试 但我也希望用于功能测试 当然不是全部 最简单的方法是什么 dev urandom仅覆盖一个进程 有没有办法做类似的事情chroot对于单个文件并
  • 如何使用Android获取Linux内核的版本?

    如何在 Android 应用程序中获取 Linux 内核的版本 不是 100 确定 但我认为调用 uname r 需要 root 访问权限 无论如何 有一种不太肮脏的方法可以做到这一点 那就是 System getProperty os v
  • Linux/POSIX:为什么 fork() 不分叉*所有*线程

    众所周知 POSIX下创建新进程的默认方式是使用fork 在 Linux 下 这在内部映射到clone 我想知道的是 众所周知 当一个人打电话时fork 子进程是用单个线程创建的 调用的线程fork cf https linux die n
  • cdc_acm:无法设置 dtr/rts - 无法与 USB cdc 设备通信

    我试图使用 pic24fj128gb206 枚举 usb cdc 设备 设备似乎已正确枚举 但是当我将设备连接到 Linux PC 时 我从内核收到以下警告消息 cdc acm 1 8 1 6 7 1 0 failed to set dtr
  • 如何让 Node.js 作为后台进程运行并且永不死掉?

    我通过 putty SSH 连接到 linux 服务器 我尝试将其作为后台进程运行 如下所示 node server js 然而 2 5 小时后 终端变得不活动 进程终止 即使终端断开连接 我是否也可以使进程保持活动状态 Edit 1 事实
  • 从 Linux 内核模块中调用用户空间函数

    我正在编写一个简单的 Linux 字符设备驱动程序 以通过 I O 端口将数据输出到硬件 我有一个执行浮点运算的函数来计算硬件的正确输出 不幸的是 这意味着我需要将此函数保留在用户空间中 因为 Linux 内核不能很好地处理浮点运算 这是设
  • 无法显示 Laravel 欢迎页面

    我的服务器位于 DigitalOcean 云上 我正在使用 Ubuntu 和 Apache Web 服务器 我的家用计算机运行的是 Windows 7 我使用 putty 作为终端 遵循所有指示https laracasts com ser

随机推荐