多线程的麻烦
多线程编程是一件麻烦的事,相信很多人深有体会。执行顺序的不确定性,资源的并发访问一直困扰着众多程序员。解决多线程编程问题的方法分为两类:一是对并发访问的资源直接加锁;二是避免并发访问资源;Chromium采用第二种思想来设计多线程模型,通过在线程之间传递消息来实现跨进程通讯。
设计原则
Chromium希望尽量保持UI处于响应状态。为此遵循如下设计原则:
1 不在UI线程上执行任何阻塞I/O操作,以及其它耗时操作。
2 少用锁和线程安全对象
3 避免阻塞I/O线程
4 线程之间不要互相阻塞
5 在数据准备好更新到共享缓冲时才用锁(在准备数据期间不要用锁)
Chromium在程序启动时创建了很多预定用途的线程,我们要尽量使用已有线程,不要创建新的线程。为了实现非阻塞代码,Chromium的很多API都是异步的。
MessageLoop
Chromium将消息循环抽象为MessageLoop类,每个线程都有(只有)一个MessageLoop实例。MessageLoop提供了PostTask系列方法允许向特定线程添加任务。MessageLoop会安装“先进先出”的顺序执行任务,直到收到MessageLoop:Quit消息,消息循环才会退出。
MessageLoop类型
每个MessageLoop都有一个类型,所有类型的MessageLoop都能够处理tasks和timers,类型指定了MessageLoop除了处理tasks和timers外,还可以处理的消息类型。
TYPE_DEFAULT:默认的消息循环,只能处理异步任务和定时器timers
TYPE_UI:除了可以处理异步任何和定时器timers,还能够处理系统UI事件。主线程使用的就是该类型的MessageLoop。
TYPE_IO:支持处理异步I/O事件,Chromium创建的所有处理IPC消息的IO线程创建的MessageLoop都是这种类型。
TYPE_JAVA&