分类: Android平台
2014-04-08 14:55:08
6.2.2 独一无二的ProcessState
我们在main函数的开始处便碰见了ProcessState。由于每个进程只有一个ProcessState,所以它是独一无二的。它的调用方式如下面的代码所示:
[-->Main_MediaServer.cpp]
- //①获得一个ProcessState实例。
- sp<ProcessState> proc(ProcessState::self());
- 下面来进一步分析这个独一无二的ProcessState。
- 1. 单例的ProcessState
- ProcessState的代码如下所示:
- [-->ProcessState.cpp]
- sp<ProcessState> ProcessState::self()
- {
- //gProcess是在Static.cpp中定义的一个全局变量。
- //程序刚开始执行,gProcess一定为空。
- if (gProcess != NULL) return gProcess;
- AutoMutex _l(gProcessMutex);
- //创建一个ProcessState对象,并赋值给gProcess。
- if (gProcess == NULL) gProcess = new ProcessState;
- return gProcess;
- }
self函数采用了单例模式,根据这个以及Process State的名字这很明确地告诉了我们一个信息:每个进程只有一个ProcessState对象。这一点,从它的命名中也可看出些端倪。
2. ProcessState的构造
再来看ProcessState的构造函数。这个函数非常重要,它悄悄地打开了Binder设备。代码如下所示:
[-->ProcessState.cpp]
- ProcessState::ProcessState()
- // Android中有很多代码都是这么写的,稍不留神 就容易忽略这里调用了一个很重要的函数。
- : mDriverFD(open_driver())
- , mVMStart(MAP_FAILED)//映射内存的起始地址。
- , mManagesContexts(false)
- , mBinderContextCheckFunc(NULL)
- , mBinderContextUserData(NULL)
- , mThreadPoolStarted(false)
- , mThreadPoolSeq(1)
- {
- if (mDriverFD >= 0) {
- /*
- BIDNER_VM_SIZE定义为(1*1024*1024) - (4096 *2) = 1M-8K
- mmap的用法希望读者man一下,不过这个函数真 正的实现和驱动有关系,而Binder驱动会分配一块
- 内存来接收数据。
- */
- mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE,
- mDriverFD, 0);
- }
- ......
- }
3.打开binder设备
open_driver的作用就是打开/dev/binder这个设备,它是Android在内核中为完成进程间通信而专门设置的一个虚拟设备,具体实现如下所示:
[-->ProcessState.cpp]
- static int open_driver()
- {
- int fd = open(“/dev/binder”, O_RDWR);//打开/dev/binder设备。
- if (fd >= 0) {
- ......
- size_t maxThreads = 15;
- //通过ioctl方式告诉binder驱动,这个fd支持的最大线程数是15个。
- result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
- }
- return fd;
- ......
- }
至此,Process::self函数就分析完了。它到底干了什么呢?总结如下:
打开/dev/binder设备,这就相当于与内核的Binder驱动有了交互的通道。
对返回的fd使用mmap,这样Binder驱动就会分配一块内存来接收数据。
由于ProcessState具有唯一性,因此一个进程只打开设备一次。
分析完ProcessState,接下来将要分析第二个关键函数defaultServiceManager。