6.2.2 独一无二的ProcessState
最后更新于:2022-04-02 05:50:23
我们在main函数的开始处便碰见了ProcessState。由于每个进程只有一个ProcessState,所以它是独一无二的。它的调用方式如下面的代码所示:
**Main_MediaServer.cpp**
~~~
//①获得一个ProcessState实例
sp proc(ProcessState::self());
~~~
下面,来进一步分析这个独一无二的ProcessState。
1. 单例的ProcessState
ProcessState的代码如下所示:
**ProcessState.cpp**
~~~
sp 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函数采用了单例模式,这很明确地告诉了我们一个信息:每个进程只有一个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。
';