关于linux下进程和线程优先级的一些总结
基础进程优先级值越小,优先级越大,进程的优先级是PRI值不是Nice值,普通进程优先级可以通过Nice值调整,实时进程不行Linux的进程分普通进程(非实时进程)和实时进程,进程调度策略优先级说明普通进程SCHED_OTHER或SCHED_NORMAL100-139这个区间的优先级又称为静态优先级,不会随着时间而改变,内核不会修改它,只能通过系统调用nice去修改,静态优先级数值越大,进程的优先级
·
1.进程
1.1 基础
进程优先级值越小,优先级越大,进程的优先级是PRI值不是Nice值,普通进程优先级可以通过Nice值调整,实时进程不行
Linux的进程分普通进程(非实时进程)和实时进程,
进程 | 调度策略 | 优先级 | 说明 |
---|---|---|---|
普通进程 | SCHED_OTHER或SCHED_NORMAL | 100-139 | 这个区间的优先级又称为静态优先级,不会随着时间而改变,内核不会修改它,只能通过系统调用nice去修改,静态优先级数值越大,进程的优先级越小,分配的基时间量就越少。 普通进程几乎是无法分到时间片的(只能分到5%的CPU时间)。 static priority=nice+20+MAX_RT_PRIO ,nice值[-20,19],MAX_RT_PRIO默认为100,这样做的好处是,任何内核态进程优先级都大于用户态的进程 |
实时进程 | SCHED_FIFO或SCHED_RR | 0-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-100 | static_priority取值是[100,139],所以top_pri取值是[0,39] |
实时进程 | top_pri=-1-real_time_priority | chrt命令就是修改实时进程的优先级,比如给进程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 (系统级竞争资源)。
/**************************************
更多推荐
已为社区贡献1条内容
所有评论(0)