关于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下进程和线程优先级的一些总结 的相关文章

随机推荐