編輯:Android資訊
在計算機操作系統中,進程是進行資源分配和調度的基本單位,同時每個進程之內也可以存在多個線程。那麼在Android系統(Linux Kernel)中,進程是如何去搶占資源,線程又是如何根據優先級切換呢,本文將嘗試剖析這個問題,研究nice在Linux以及Android系統中的應用。
Linux中,使用nice value(以下成為nice值)來設定一個進程的優先級,系統任務調度器根據nice值合理安排調度。
nice這個命令的來源幾乎沒有資料提到,於是便嘗試自己來推斷一下。在諸如詞霸,滬江等詞典給出的意思均為好的;美好的;可愛的;好心的,友好的。而有道詞典則稍微給出了一個其他詞典沒有的和藹的。個人認為有道給出的這個比較合理。要想做到和藹,就需要做到謙讓,因此或多或少犧牲自己一點,成全他人。所以nice值越高,越和藹,但是自己的優先級也會越低。
對於一個新的進程我們可以按照下面的代碼為一個進程設定nice值。
nice -n 10 adb logcat
對於已經創建的進程,我們可以使用renice來修改nice值
sudo renice -n 0 -p 24161
該命令需要使用root權限,-p對應的值為進程id。
注意renice命令在Linux發行版中-n 的值應該為進程的目標優先級。而Mac下-n,則是代表對當前權限的增加值。 比如在Mac下,講一個進程的nice值由19改成10,可以這樣操作sudo renice -n -9 -p 24161,這一點需要注意,避免掉進坑裡。
由於Android基於Linux Kernel,在Android中也存在nice值。但是一般情況下我們無法控制,原因如下:
雖然對於進程的優先級,我們無法控制,但是我們可以控制進程中的線程的優先級。在Android中有兩種線程的優先級,一種為Android API版本,另一種是 Java 原生版本。
Android中的線程優先級別目前規定了如下,了解了進程優先級與nice值的關系,那麼線程優先級與值之間的關系也就更加容易理解。
使用Android API為線程設置優先級也很簡單,只需要在線程執行時調用android.os.Process.setThreadPriority方法即可。這種在線程運行時進行修改優先級,效果類似renice。
new Thread () { @Override public void run() { super.run(); android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); } }.start();
Java為Thread提供了三個級別的設置,
使用setPriority我們可以為某個線程設置優先級,使用getPriority可以獲得某個線程的優先級。
在Android系統中,不建議使用Java原生的API,因為Android提供的API劃分的級別更多,更適合在Android系統中進行設定細致的優先級。
Android API的線程優先級和Java原生API的優先級是相對獨立的,比如使用 android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND) 後,使用Java原生API,Thread.getPriority()得到的值不會改變。如下面代碼:
new Thread() { @Override public void run() { super.run(); Log.i(LOGTAG, "Java Thread Priority Before=" + Thread.currentThread().getPriority()); Process.setThreadPriority(Process.THREAD_PRIORITY_LOWEST); Log.i(LOGTAG, "Java Thread Priority=" + Thread.currentThread().getPriority()); } }.start();
上述代碼的運行日志為
I/MainActivity( 3679): Java Thread Priority Before=5 I/MainActivity( 3679): Java Thread Priority=5
由於上面的這一點缺陷,導致我們在分析ANR trace時需要注意,在下面的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)
我在之前的文章說說Android中的ANR中提到使用WorkerThread處理耗時IO操作,同時將WorkerThread的優先級降低,對於耗時IO操作,比如讀取數據庫,文件等,我們可以設置該workerThread優先級為THREAD_PRIORITY_BACKGROUND,以此降低與主線程競爭的能力。
基於Android 6.0的源碼,剖析存儲架構的設計 Android 存儲系統之源碼篇 Android 存儲系統之架構篇 一、概述 本文講述Android存儲系統
Android安全加密專題文章索引 Android安全加密:對稱加密 Android安全加密:非對稱加密 Android安全加密:消息摘要Message Dig
本文由碼農網 – 小峰原創,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃! ASimpleCache是一款基於Android的輕量級緩存框架,它只
Android中Handler可以異步控制Runnable,那麼這樣做於Android中的Thread有什麼區別呢?本文將通過多個角度來講解這個問題,讀完此文,相