Chromium 的多线程机制
概述
-
每个进程都有很多的线程;
-
多线程主要是为了保证
UI
线程(chrome 线程,主线程)不会被任何其它费时的操作阻碍而影响对用户的响应; -
为了解决多线程通信和同步问题,
Chromium
的机制是绝大多数的场景使用事件和一种chromium
新创建的任务传递机制,仅在非用不可的情况下使用锁或者线程安全对象,这有严格的要求; -
Chromium
在每个线程内部通过MessageLoop
如何处理事件和任务;
-
几个重要和诡异的线程:
*chrome
线程:进程的主线程,browser
进程中主要是负责 UI,当然也是管家;Renderer
进程中则是管家兼处理WebKit
渲染;gpu
进程中则是负责处理绘图请求并调用openGL
进行绘制工作。
*Chrome_IOThread/Chrome_ChildIOThread
线程:用来接受来自其它进程的IPC
消息和派发自身消息到其它进程;
*SignalSender
线程:V8 JavaScript
引擎中用于处理Linux
信号的线程;
任务
Chromium
的特色就是在事件的基础上,加入了新的机制-任务;当要执行某个操作时,把该操作封装成一个任务,由任务派发机制传递给相应的进程的MessageLoop
;- 线程内部的进行:
* 当需要进行费时的操作时候,派发一个事件和回调函数给自身线程的MessageLoop
,然后MessageLoop
会调度该回调函数以执行其操作;
* 线程间通信: 假如一个线程A
需要把任务传递给一个另外的线程B
, 首先,A
把任务传递给B
;其次,B
调度执行该任务;最后,B
执行完任务后回复A
;很多情况下,线程A
不需要回复。
消息循环
Chromium
里,需要处理三种类型的消息:
*chromium
自定义的任务; //平台无关
*Socket
或者文件等IO
操作; //平台相关
* 用户界面(UI)的消息; //平台相关- 典型线程例子
* 主线程(UI线程)需要处理UI
相关的消息和自定义任务;
*IO
线程则需要处理Socket
和自定义任务;
*History
线程则只需要处理自定义任务;
* 其它线程需要处理消息类型不会超出以上三个线程;
Chromium
中主要的类
- 类
RunLoop
:一个辅助类,主要封装消息循环MessageLoop
类,主要提供一组公共接口被调用,实质是调用MessageLoop
类的接口和实现; - 类
MessagePump
: 一个抽象出来的基类,可以用来处理第二和第三种消息类型;对于每个平台,它们有不同的子类来对应; - 类
MessageLoop
:主消息循环,原理上讲,应该可以处理三种类型的消息,实际上通过实现MessagePumpDelegate
的接口来负责处理自定义任务;
无限循环
- 消息循环本质就是一个无限循环,不停的处理消息循环接收到的任务和消息,直到需要推出为止;
- 等待自定义的任务, 以
MessagePumpLibEvent
为例:在Linux
平台上, 该类创建一个管道,它等待读取这个管道的内容,当有自定义的新任务到来时,写入一个字节到这个管道,从而MessageLoop
被唤醒;