亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Binder線程池工作過程是什么

發布時間:2022-03-25 09:32:10 來源:億速云 閱讀:365 作者:iii 欄目:互聯網科技

這篇文章主要介紹了Binder線程池工作過程是什么的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Binder線程池工作過程是什么文章都會有所收獲,下面我們一起來看看吧。

基于Android 6.0源碼剖析,分析Binder線程池以及binder線程啟動過程。
Binder線程池工作過程是什么

一. 概述

Android系統啟動完成后,ActivityManager, PackageManager等各大服務都運行在system_server進程,app應用需要使用系統服務都是通過binder來完成進程之間的通信,那對于binder線程是如何管理的呢,又是如何創建的呢?其實無論是system_server進程,還是app進程,都是在進程fork完成后,便會在新進程中執行onZygoteInit()的過程中,啟動binder線程池。接下來,就以此為起點展開從線程的視角來看看binder的世界。

二. Binder線程創建

Binder線程創建與其所在進程的創建中產生,Java層進程的創建都是通過Process.start()方法,向Zygote進程發出創建進程的socket消息,Zygote收到消息后會調用Zygote.forkAndSpecialize()來fork出新進程,在新進程中會調用到RuntimeInit.nativeZygoteInit方法,該方法經過jni映射,最終會調用到app_main.cpp中的onZygoteInit,那么接下來從這個方法說起。

2.1 onZygoteInit

[-> app_main.cpp]

Binder線程池工作過程是什么

ProcessState::self()是單例模式,主要工作是調用open()打開/dev/binder驅動設備,再利用mmap()映射內核的地址空間,將Binder驅動的fd賦值ProcessState對象中的變量mDriverFD,用于交互操作。startThreadPool()是創建一個新的binder線程,不斷進行talkWithDriver()。

2.2 PS.startThreadPool

[-> ProcessState.cpp]

Binder線程池工作過程是什么

啟動Binder線程池后, 則設置mThreadPoolStarted=true. 通過變量mThreadPoolStarted來保證每個應用進程只允許啟動一個binder線程池, 且本次創建的是binder主線程(isMain=true). 其余binder線程池中的線程都是由Binder驅動來控制創建的。

2.3 PS.spawnPooledThread

[-> ProcessState.cpp]

Binder線程池工作過程是什么

獲取Binder線程名,格式為Binder_x, 其中x為整數。每個進程中的binder編碼是從1開始,依次遞增; 只有通過spawnPooledThread方法來創建的線程才符合這個格式,對于直接將當前線程通過joinThreadPool加入線程池的線程名則不符合這個命名規則。 另外,目前Android N中Binder命令已改為Binder:_x格式, 則對于分析問題很有幫忙.

2.3.2 PoolThread.run

[-> ProcessState.cpp]

Binder線程池工作過程是什么

  • 對于isMain=true的情況下, command為BC_ENTER_LOOPER,代表的是Binder主線程,不會退出的線程;

  • 對于isMain=false的情況下,command為BC_REGISTER_LOOPER,表示是由binder驅動創建的線程。

2.5 processPendingDerefs

[-> IPCThreadState.cpp]

Binder線程池工作過程是什么

2.6 getAndExecuteCommand

[-> IPCThreadState.cpp]

Binder線程池工作過程是什么

2.7 talkWithDriver

Binder線程池工作過程是什么

在這里調用的isMain=true,也就是向mOut例如寫入的便是BC_ENTER_LOOPER. 經過talkWithDriver(), 接下來程序往哪進行呢?從binder_thread_write()往下說BC_ENTER_LOOPER的處理過程。
2.7.1 binder_thread_write

[-> binder.c]

Binder線程池工作過程是什么

Binder線程池工作過程是什么

Binder線程池工作過程是什么

Binder線程池工作過程是什么

當發生以下3種情況之一,便會進入done:

  • 當前線程的return_error發生錯誤的情況;

  • 當Binder驅動向客戶端發送死亡通知的情況;

  • 當類型為BINDER_WORK_TRANSACTION(即收到命令是BC_TRANSACTION或BC_REPLY)的情況;

任何一個Binder線程當同時滿足以下條件,則會生成用于創建新線程的BR_SPAWN_LOOPER命令:

  1. 當前進程中沒有請求創建binder線程,即requested_threads = 0;

  2. 當前進程沒有空閑可用的binder線程,即ready_threads = 0;(線程進入休眠狀態的個數就是空閑線程數)

  3. 當前進程已啟動線程個數小于最大上限(默認15);

  4. 當前線程已接收到BC_ENTER_LOOPER或者BC_REGISTER_LOOPER命令,即當前處于BINDER_LOOPER_STATE_REGISTERED或者BINDER_LOOPER_STATE_ENTERED狀態。【小節2.6】已設置狀態為BINDER_LOOPER_STATE_ENTERED,顯然這條件是滿足的。

從system_server的binder線程一直的執行流:IPC.joinThreadPool - > IPC.getAndExecuteCommand() - > IPC.talkWithDriver(),但talkWithDriver收到事務之后,便進入IPC.executeCommand(),接下來,從executeCommand說起。

2.8 IPC.executeCommand

Binder線程池工作過程是什么

Binder主線程的創建是在其所在的進程創建的過程一起創建的,后面再創建的普通binder線程是由spawnPooledThread(false)方法所創建的。

2.9思考

默認地,每個進程的binder線程池的線程個數上限為15,該上限不統計通過BC_ENTER_LOOPER命令創建的binder主線程,只計算BC_REGISTER_LOOPER命令創建的線程對此,或者很多人不理解,例栗子:某個進程的主線程執行如下方法,那么該進程可創建的binder線程個數上限是多少呢?

Binder線程池工作過程是什么

首先線程池的binder線程個數上限為6個,通過startThreadPool()創建的主線程不在最大線程上限,最后一句是將當前線程成為binder線程,所以說可創建的binder線程個數上限為8 ,如果還不理解,建議再多看看這幾個方案的源碼,多思考整個binder架構。

三。總結

Binder設計架構中,只有第一個Binder主線程(也就是Binder_1線程)是由應用程序主動創建,Binder線程池的普通線程都是由Binder驅動根據IPC通信需求創建,Binder線程的創建流程圖:

Binder線程池工作過程是什么

每次由Zygote fork出新進程的過程中,伴隨著創建binder線程池,調用spawnPooledThread來創建binder主線程。當線程執行binder_thread_read的過程中,發現當前沒有空閑線程,沒有請求創建線程,且沒有達到上限,則創建新的binder線程。

Binder的交易有3種類型:

  1. 調用:發起進程的線程不一定是在Binder線程,大多數情況下,接收者只指向進程,并不確定會有哪個線程來處理,所以不指定線程;

  2. 答復:發起者一定是binder線程,并且接收者線程便是上次call時的發起線程(該線程不一定是binder線程,可以是任意線程)。

  3. async:與調用類型差不多,唯一不同的是async是oneway方式不需要回復,發起進程的線程不一定是在Binder線程,接收者只指向進程,并且不確定會有哪個線程來處理,所以不指定線程。

Binder系統中可分為3類binder線程:

  • Binder主線程:進程創建過程會調用startThreadPool()過程中再進入spawnPooledThread(true),來創建Binder主線程。編號從1開始,也就是意味著binder主線程名為binder_1,并且主線程是不會退出的。

  • Binder普通線程:是由Binder Driver來根據是否有空閑的binder線程來決定是否創建binder線程,回調spawnPooledThread(false),isMain = false,該線程名格式為binder_x。

  • Binder其他線程其他線程是指并沒有調用spawnPooledThread方法,而是直接調用IPC.joinThreadPool(),將當前線程直接加入binder線程隊列。例如:mediaserver和servicemanager的主線程都是binder線程,但system_server的主線程并非binder線程。

關于“Binder線程池工作過程是什么”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Binder線程池工作過程是什么”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

大渡口区| 通榆县| 南漳县| 健康| 明溪县| 深水埗区| 浦城县| 米泉市| 涟源市| 日土县| 株洲县| 登封市| 张家口市| 夏邑县| 潼关县| 霍州市| 南充市| 和田市| 曲阜市| 黄浦区| 夏邑县| 冕宁县| 女性| 安远县| 莲花县| 红河县| 凯里市| 宣化县| 芒康县| 通江县| 噶尔县| 沾益县| 郑州市| 响水县| 呼图壁县| 德昌县| 越西县| 苍山县| 尚义县| 耿马| 河源市|