binder 与 ProcessState & IPCThreadState
2016-11-08 17:15
567 查看
每次看binder相关内容时,都会牵扯到这两个类,每次都看也能理解。不过工作中用的少,脑袋记性不好,所以留下的印象并不是很深刻,这次下定决心,要记下来,下次不翻别人的资料和代码了,直接来瞄一眼自己写的,很快就会回忆起来。如果说直观印象,我脑袋里立马能跳出来两句话:“启动线程池”,“加入线程池”。然后,我是越来越讨厌自己的囫囵吞枣了,我会逐渐把一切都弄清楚。一点点去地去扩充自己的理解。每个进程都会有对象的binder守护线程来负责通信,app会有,native进程会有。app进程的binder驱动程序初始化的工作,是在启动app过程中默认完成。native进程一般都是显示调用上面两个类的方法来完成工作。参考代码:aosp6.0
应用进程的binder初始化
zygote的socket收到system进程发送过来的启动app的消息后,通过fork创建出子进程,这个子进程就是我们需要启动的app进程。子进程创建后,调用 static 方法RuntimeInit.zygoteInit,该方法中,调用 native 方法 nativeZygoteInit(),就是在这个native方法中,完成了binder相关的初始化工作。该jni方法注册的地方在: framework/base/cor/jni/AndroidRuntime.cpp:static JNINativeMethod gMethods[] = { {"nativeZygoteInit", "()V", (void *)com_android_internal_os_RuntimeInit_nativeZygoteInit} }native层的实现:
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz) { gCurRuntime->onZygoteInit(); }gCurRuntime又是什么鬼? “望文生义”一下,应该是 global current runtime,即全局的运行时。定义为:
static AndroidRuntime* gCurRuntime = NULL;可以理解为运行环境的上下文,我个人理解,虚拟机(dalvik,art)是这个上下文的组成部分。
onZygoteInit()的实现在app_main.cpp的AppRuntime类中,该类继承AndroidRuntime。
virtual void onZygoteInit() { sp<ProcessState> proc = ProcessState::self(); ALOGV("App process: starting thread pool.\n"); proc->startThreadPool(); }在onZygoteInit()中,终于看到了这次分析的目标:ProcessState以及该类的方法startThreadPool().
ALOGV中的信息很明确地说明了,下一步的操作是启动线程池。
ProcessState::self获得了该类的单例对象。
/frameworks/native/libs/binder/ProcessState.cpp:
void ProcessState::startThreadPool() { AutoMutex _l(mLock); if (!mThreadPoolStarted) { mThreadPoolStarted = true; spawnPooledThread(true); } }先判断线程池有没有已经启动,如果没有启动,调用spawnPooledThread(true)来启动。
void ProcessState::spawnPooledThread(bool isMain) { if (mThreadPoolStarted) { String8 name = makeBinderThreadName(); ALOGV("Spawning new pooled thread, name=%s\n", name.string()); sp<Thread> t = new PoolThread(isMain); t->run(name.string()); } }这里面,启动了一个PoolThread,该类继承自Thread。
该类的定义仍在 framework/base/cor/jni/AndroidRuntime.cpp 中
class PoolThread : public Thread { public: PoolThread(bool isMain) : mIsMain(isMain) { } protected: virtual bool threadLoop() { IPCThreadState::self()->joinThreadPool(mIsMain); return false; } const bool mIsMain; };突然间发现,另一个目标出现了:
IPCThreadState::self()->joinThreadPool(mIsMain);
frameworks/native/libs/binder/IPCThreadState.cpp:
void IPCThreadState::joinThreadPool(bool isMain){mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);......status_t result;do {processPendingDerefs();// now get the next command to be processed, waiting if necessaryresult = getAndExecuteCommand();......} while (result != -ECONNREFUSED && result != -EBADF);......mOut.writeInt32(BC_EXIT_LOOPER);talkWithDriver(false);}mOut可以理解为和binder驱动共享的消息管道,app进程往里面write消息,binder驱动就会读到。同时,app进程也从mIn里面read从binder驱动中写的消息。
joinThreadPool()方法,中,开始和结束分别执行了一次write操作:
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);和
mOut.writeInt32(BC_EXIT_LOOPER);
分别通知binder进入和退出消息循环。
在循环过程中,通过getAndExecuteCommand()方法,从mIn中读取消息,并执行相关的命令。
status_t IPCThreadState::getAndExecuteCommand(){status_t result;int32_t cmd;result = talkWithDriver();if (result >= NO_ERROR) {......result = executeCommand(cmd);......}return result;}getAndExcuteCommand()自然分为两步操作:
1. get: talkWithDriver() // 获取消息
2. excute: executeCommand() // 解析出command之后,执行相关操作
talkWithDriver()就是用一些文件操作函数读写消息,这里先不表了。
以上是应用进程启动binder线程的相关步骤。
在我门播放音乐时,是通过binder和media进程里面的一些native service来通信的。这些native进程的binder线程,是怎么启动的呢?就以native media来举例说明:
native 进程中的binder的初始化
先谈一下media进程。android很多多媒体相关的服务,都是放在media进程中的。包括audio flinger,media player,camera service等。这个进程,是在init进程中启动的。
service media /system/bin/mediaserverclass mainuser mediagroup audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrmioprio rt 4进程名称:media,可执行的程序地址:/system/bin/mediaserver
代码路径:frameworks/ava/media/mediaserver/main_mediaserver.cpp
入口函数当然是main():
int main(int argc __unused, char** argv){signal(SIGPIPE, SIG_IGN);char value[PROPERTY_VALUE_MAX];bool doLog = (property_get("ro.test_harness", value, "0") > 0) && (atoi(value) == 1);pid_t childPid;if (doLog && (childPid = fork()) != 0) {} else {....InitializeIcuOrDie();sp<ProcessState> proc(ProcessState::self());sp<IServiceManager> sm = defaultServiceManager();ALOGI("ServiceManager: %p", sm.get());AudioFlinger::instantiate();MediaPlayerService::instantiate();ResourceManagerService::instantiate();CameraService::instantiate();AudioPolicyService::instantiate();SoundTriggerHwService::instantiate();RadioService::instantiate();registerExtensions();ProcessState::self()->startThreadPool();IPCThreadState::self()->joinThreadPool();}}这里面,先后启动了一些media service,然后就很直接到调用了ProcessState的startThreadPool()和IPCThreadState的joinThreadPool().这样,我们在app中
请求的一些media相关的服务,在media server进程中就会通过binder线程得知,从而执行相关的任务,完成后,把结果或者执行状态再通过binder返回到app进程中。
以上就是在应用进程中和native进程中,binder线程的大概的启动过程。
相关文章推荐
- Android Binder ProcessState & IPCThreadState相关介绍
- Android Binder ProcessState & IPCThreadState相关介绍
- Android - Binder机制 - ProcessState和IPCThreadState
- Android - Binder机制 - ProcessState和IPCThreadState
- Android - Binder机制 - ProcessState和IPCThreadState
- Android5.0中Binder相关的ProcessState和IPCThreadState的认识.
- Android - Binder机制 - ProcessState和IPCThreadState
- Binder中的ProcessState和IPCThreadState分析
- 每天一点点——thread&process
- 解决cygwin上编译boost for android 的thread库找不到"process.h"
- Process&Thread 示例
- Check the state of child process./thread in java
- Operating System-Process(1)什么是进程&&进程的创建(Creation)&&进程的终止(Termination)&&进程的状态(State)
- 常见错误 不能打开注册表关键字 'Temporary (volatile) Jet DSN for process 0xbec Thread 0xd34 DBC 0x3510024 Jet'
- java层aidl细节_ipc & ibinder-binder & aidl
- Exception in thread "main" java.io.IOException: Cannot run program "XX": CreateProcess error
- [Android]Process&Thread-基本原理
- process state & process queue
- process-->thread-->coroutine
- Process & Thread 进程和线程