在Binder通信机制里,客户端与服务端之间的通信是在专门的IPC通信线程中进行的。这些线程构成一个线程池。线程的创建和销毁是在用户空间进行的,而对线程的控制是在驱动层进行的,即驱动控制线程池中线程的生命,而线程本身则是运行在用户空间的。驱动层是通过BR_SPAWN_LOOPER向用户空间发送创建新线程的命令。
线程池的大小可以设置, 如果没有主动去设置这个大小,则默认大小为15,如下代码所示:
在ProcessSate.cpp在构造函数里,会调用open_driver函数,里面会进行线程池默认大小的设置:
static int open_driver()
{
int fd = open("/dev/binder", O_RDWR);
if (fd >= 0) {
...
size_t maxThreads = 15;
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
if (result == -1) {
ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
}
} else {
ALOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));
}
return fd;
}
与线程池相关的几个变量设置在struct binder_proc结构体中:
struct binder_proc {
...
int max_threads;//max thread
int requested_threads;//
int requested_threads_started;//requested thread seq No
int ready_threads;//available for use
...
};
其中,max_threads表示当前进程线程池的大小。ioctl命令BINDER_SET_MAX_THREADS用来设置这个值,默认情况下是15,如上所述。ready_threads表示当前线程池中有多少可用的空闲线程。requested_threads请求开启线程的数量。requested_threads_started表示当前已经接受请求开启的线程数量。
对于IPC通信的服务端进程,一般会执行如下的调用启动线程池:
ProcessState::self()->setThreadPoolMaxThreadCount(4);
ProcessState::self()->startThreadPool();
IPCThread