程序優先順序
執行緒與程序的最大區別就是是否共享父程序的地址空間,核心角度來看沒有執行緒與程序之分,都用task_struct結構體來表示,排程器操作的實體便是task_struct。
一、 程序優先順序
程序可劃分為普通程序和實時程序,那麼優先順序與nice值的關係圖:
優先順序值越小表示程序優先順序越高,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。
選擇和設定合理的程序優先順序和排程器是效能優化的一個方向,後續再以核心排程器的角度來分析排程策略的抉擇問題。