ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
以MS为例,现在程序运行正常。此时MS: (1)通过startThreadPool启动了一个线程,这个线程在talkWithDriver。 (2)主线程通过joinThreadPool,也在talkWithDriver。 至此我们已知道,有两个线程在和Binder设备打交道。这时在业务逻辑上需要与ServiceManager交互,比如要调用listServices打印所有服务的名字,假设这是MS中的第三个线程。按照之前的分析,它最终会调用IPCThreadState的transact函数,这个函数会talkWithDriver并把请求发到ServiceManager进程,然后等待来自Binder设备的回复。那么现在一共有三个线程(不论是在等待来自其他Client的请求,还是在等待listService的回复)都在talkWithDriver。 ServiceManager处理完了listServices,把回复结果写回Binder驱动,那么,MS中哪个线程会收到回复呢?此问题如图6-6表示: :-: ![](http://img.blog.csdn.net/20150802155858040?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 图6-6 本问题的示意图 显而易见,当然是调用listServices的那个线程会得到结果。为什么?因为如果不这么做,则会导致下面情况的发生: - 如果是没有调用listServices的线程1或者线程2得到回复,那么它们应该唤醒调用listServices的线程3。因为这时已经有了结果,线程3应该从listServices函数调用中返回。 - 这其中的线程等待、唤醒、切换会浪费不少宝贵的时间片,而且代码逻辑会极其复杂。 看来,Binder设备把发起请求的线程牢牢地拴住了,必须收到回复才能放它离开。这种一一对应的方式极大简化了代码层的处理逻辑。 * * * * * **说明**:想想socket编程吧,同一时刻不能有多个线程操作socket的读/写,否则数据会乱套。 另外,我们再分析executeCommand的时候,特别提到BR_SPAWN_LOOPER这个case的处理,它用于建立新的线程来和Binder通信。什么会收到这个消息呢?请读者研究binder的驱动。如果有新发现,请告诉我,大家再一起学习。 * * * * *