1. 程式人生 > >程序優先順序

程序優先順序

執行緒與程序的最大區別就是是否共享父程序的地址空間,核心角度來看沒有執行緒與程序之分,都用task_struct結構體來表示,排程器操作的實體便是task_struct。

一、 程序優先順序

程序可劃分為普通程序和實時程序,那麼優先順序與nice值的關係圖:

nice_prio

優先順序值越小表示程序優先順序越高,3個程序優先順序的概念:

  • 靜態優先順序: 不會時間而改變,核心也不會修改,只能通過系統呼叫改變nice值的方法區修改。優先順序對映公式: static_prio = MAX_RT_PRIO + nice + 20,其中MAX_RT_PRIO = 100,那麼取值區間為[100, 139]

    ;對應普通程序;

  • 實時優先順序:只對實時程序有意義,取值區間為[0, MAX_RT_PRIO -1],其中MAX_RT_PRIO = 100,那麼取值區間為[0, 99];對應實時程序;

  • 動態優先順序: 排程程式通過增加或減少程序靜態優先順序的值,來達到獎勵IO消耗型或懲罰cpu消耗型的程序,調整後的程序稱為動態優先順序。區間範圍[0, MX_PRIO-1],其中MX_PRIO = 140,那麼取值區間為[0,139]

nice值

nice∈[-20, 19],可通過adb直接修改某個程序的nice值: renice prio pid

二、 Framework排程策略

程式碼路徑: framework/base/core/android/os/Process.java

2.1 程序優先順序

Android程序優先順序,總分10級

優先順序排程方法:

setThreadPriority(int tid, int priority)

程序優先順序級別:

程序優先順序 nice值 解釋
THREAD_PRIORITY_LOWEST 19 最低優先順序
THREAD_PRIORITY_BACKGROUND 10 後臺
THREAD_PRIORITY_LESS_FAVORABLE 1 比預設略低
THREAD_PRIORITY_DEFAULT 0 預設
THREAD_PRIORITY_MORE_FAVORABLE -1 比預設略高
THREAD_PRIORITY_FOREGROUND -2 前臺
THREAD_PRIORITY_DISPLAY -4 顯示相關
THREAD_PRIORITY_URGENT_DISPLAY -8 顯示(更為重要),input事件
THREAD_PRIORITY_AUDIO -16 音訊相關
THREAD_PRIORITY_URGENT_AUDIO -19 音訊(更為重要)

2.2 組優先順序

程序/執行緒組優先順序排程方法:

setProcessGroup(int pid, int group)
setThreadGroup(int tid, int group)

程序組優先順序級別:

組優先順序 取值 解釋
THREAD_GROUP_DEFAULT -1 僅用於setProcessGroup,將優先順序<=10的程序提升到-2
THREAD_GROUP_BG_NONINTERACTIVE 0 CPU分時的時長縮短
THREAD_GROUP_FOREGROUND 1 CPU分時的時長正常
THREAD_GROUP_SYSTEM 2 系統執行緒組
THREAD_GROUP_AUDIO_APP 3 應用程式音訊
THREAD_GROUP_AUDIO_SYS 4 系統程式音訊

2.3 排程器選擇

排程器設定方法:

setThreadScheduler(int tid, int policy, int priority)

排程器類別

排程器 名稱 解釋
SCHED_OTHER 預設 標準round-robin分時共享策略
SCHED_BATCH 批處理排程 針對具有batch風格(批處理)程序的排程策略
SCHED_IDLE 空閒排程 針對優先順序非常低的適合在後臺執行的程序
SCHED_FIFO 先進先出 實時排程策略,android暫未實現
SCHED_RR 迴圈排程 實時排程策略,android暫未實現

三、 Kernel排程策略

設定優先順序,Kernel不區別執行緒和程序,都對應同一個資料結構Task。Linux kernel用nicer值來描述程序的排程優先順序,該值越大,表明該程序越友(nice),其被排程執行的機率越低。

3.1 優先順序

int setpriority(int which, int who, int prio);

引數說明:

  • which和who引數聯合使用:
    • 當which為PRIO_PROGRESS時,who代表一個程序;
    • 當which為PRIO_PGROUP時,who代表一個程序組;
    • 當which為PRIO_USER時,who代表一個uid。
  • prio引數用於設定應用程序的nicer值,可取範圍從-20到19。

3.2 排程器

int sched_setscheduler(pid_t pid, int policy, conststruct sched_param *param);

引數說明:

  • pid為程序id;
  • policy為排程策略;
  • param最重要的是該結構體中的sched_priority變數;
    • 針對Android中的三種非實時Scheduler策略,該值必須為NULL。

選擇和設定合理的程序優先順序和排程器是效能優化的一個方向,後續再以核心排程器的角度來分析排程策略的抉擇問題。