Android nice在进程与线程调度中的作用

时间:2021-05-25 04:07:57

基本概念:

进程:计算机进行资源分配和高度的基本单位,是程序运行的实体,也是线程的容器。

线程:是进程中实际执行的单元,是程序执行的最小单元,属于一个进程。

一个进程可以拥有多个线程。


nice在进程调试中作用

在Android中,可以使用nice值来设定一个进程的优先级,系统的调度器可以根据nice值来合理的调度进程,主要特点如下:

  • 在Android中,nice的取值范围为-20~19
  • 在Android中,nice值的默认大小为0
  • 在Android中,nice值越大,进程的优先级越低,获得的CPU调用机会就越少;nice值越高,进程的优先级越高,获得的CPU调用机会越多
  • 在Android中,父进程fork出来的子进程nice值与父进程相同,你进程renice后,子进程的nice值不会改变


如何更改进程的nice值

Android中可用如下命令更改进程的nice值,

  • usage: nice [-n PRIORITY] command [args...]

    Run a command line at an increased or decreased scheduling priority.

    Higher numbers make a program yield more CPU time, from -20 (highest
    priority) to 19 (lowest).  By default processes inherit their parent's
    niceness (usually 0).  By default this command adds 10 to the parent's
    priority.  Only root can set a negative niceness level.


  • USAGE: renice [[-r] [-t TYPE] priority pids ...] [-g pid]

其中nice命令用于设置一个新创建的进程的优先级,而renice命令用于更改已经创建的进程的优先级,且这两个命令都需要在root权限下运行。


线程调度

在Android开发中,我们用的最多的是对于线程优先级的控制,但在Android中,出现了两种版本的线程优先级控制:JAVA版本和Android版本,两种版本的优先级的主要差别如下:

  • JAVA版本中的优先级使用java.lang.Thread中的setPriority(int priority)和getPriority()设置和获得线程的优先级,其只包括三种类型的线程优先级,属于粗粒度控制,如下:

       public static final intMAX_PRIORITY = 10

       public static final intMIN_PRIORITY = 5

       public static final intMIN_PRIORITY = 1

  而Android版本中的线程优先级使用android.os.Process类中的setThreadPriority(int priority)和getPriority()设置和  获得线程的优先级,其包括10中线程优先级,相对于JAVA的属于细粒度控制策略,如下:

    Android nice在进程与线程调度中的作用

  因此,在设置和获取线程优先级时,建议使用Android版本的API。

  • Android API的线程优先级和JAVA原生API的优先级是相对独立的,比如使用 android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND) 后,使用Java原生API,Thread.getPriority()得到的值不会改变。

由于上术第二点的差别,导致在分析ANR log时需要格外注意,在下面的ANR日志信息中,prio=5中proi的值对应的JAVA原生API的线程优先级。而nice=-6中的nice表示的Android API版本的线程优先级。

"main" prio=5 tid=1 NATIVE
  | group="main" sCount=1 dsCount=0 obj=0x41690f18 self=0x4167e650
  | sysTid=1765 nice=-6 sched=0/0 cgrp=apps handle=1074196888
  | state=S schedstat=( 0 0 0 ) utm=5764 stm=3654 core=2
  #00  pc 00022624  /system/lib/libc.so (__futex_syscall3+8)
  #01  pc 0000f054  /system/lib/libc.so (__pthread_cond_timedwait_relative+48)
  #02  pc 0000f0b4  /system/lib/libc.so (__pthread_cond_timedwait+64)