分享

server端threadPool的管理

 lifei_szdz 2014-02-16

所谓的LOOPER就是线程池的无限循环,先来看看LOOPER相关的枚举量:
enum {
BINDER_LOOPER_STATE_REGISTERED = 0x01,
BINDER_LOOPER_STATE_ENTERED = 0x02,
BINDER_LOOPER_STATE_EXITED = 0x04,
BINDER_LOOPER_STATE_INVALID = 0x08,
BINDER_LOOPER_STATE_WAITING = 0x10,
BINDER_LOOPER_STATE_NEED_RETURN = 0x20
};  //表示线程状态

 

如果一个线程想加入线程池,获取进程work时,必须先告知驱动,需要通过write发送BC_ENTER_LOOPER或者BC_REGISTER_LOOPER命令给驱动以表明自己进入了线程池循环,可以接受进程work,驱动会根据命令设置线程的looper的ENTERED或者REGISTERED标志位。一个线程(不一定加入了线程池)如果没有事情可做,在read阶段阻塞时,WAITING标记被设置。

 

BC_ENTER_LOOPER和BC_REGISTER_LOOPER都是用来将线程注册到驱动,以便他们能够获取进程work。前者适用于应用程序自己主动产生的线程,比如主线程以及startThreadPool产生的第一个线程。

 

任何一个线程在read阶段返回时,会检查进程的ready_threads,这个变量表示当前进程有多少个线程正在等待进程work,这类线程必然处于WAITING状态(反过来不一定成立^-^)。如果当前没有线程等待进程work,驱动在read的返回BR队列最前面加上一个BR_SPAWN_LOOPER通知该线程,线程池已经没有可用于处理进程work的线程了,你得赶紧给我产生一个新的,线程在read返回之后便会根据该BR创建一个新的线程,并让它BC_REGISTER_LOOPER加入线程池并待命,然后自己才去处理这次read到的真正work,这样可以缩短线程池的真空期。

 

这里有点小优化,如果驱动已经要求某个线程生成一个新的线程,在这个线程还没加入线程池前,驱动不会在别的线程read返回时再次要求生成新线程,这样可以避免要求进程生成过多的线程。这件事情是通过进程的requested_threads变量实现的,在read返回BR_SPAWN_LOOPER时,此变量被增加,在新的线程BC_REGISTER_LOOPER成功时此变量被减小,用来表明生成线程的工作已经完成,而通过这种方式生成的线程数会被记录到进程的reqeusted_threads_started,这种方式生成的线程数不能超过进程的max_threads

 

如果到了MAX后,线程池中的线程还不够响应远程请求时,用户进程可以自行生成新的线程并用BC_ENTER_LOOPER注册到线程池用来提供服务。不过一般没必要这么做,线程多了并不见得能改善服务速度,还不如让请求等待着,直到线程池已有的线程完成手头工作再去响应新的请求。

 

BC_REGISTER_LOOPER命令给驱动以表明自己进入了线程池循环,可以接受进程工作,前者适用于应用程序自己主动产生的线程,比如主线程以及startThreadPool产生的第一个线程

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多