Chrome源代码分析之进程和线程模型(三

Chrome源代码分析之进程和线程模型(三)
https://blog.csdn.net/namelcx/article/details/6582730

关于Chrome的线程模型,在他的开发文档中有专门的介绍,原文地址在这里:http://dev.chromium.org/developers/design-documents/threading

chrome的进程,chrome没有采用一般应用程序的单进程多线程的模型,而是采用了多进程的模型,按照他的文字说明,主界面框架下的一个TAB就对应这个一个进程。但实际上,一个进程不仅仅包含一个页面,实际上同类的页面在共用一个进程。

chrome进程模型下有2种进程,一个是Browser进程。另一种是Renderer进程,Browser只有一个,主控整个系统的运行,而Renderer则可以有多个,主要负责页面的渲染和显示。

Browser作为主进程最先启动,Browser包含一个主线程mainthread,在mainthread中对整个系统进行初始化,并启动为另外几个线程,看下面的代码:

void CreateChildThreads(BrowserProcessImpl* process) {
process->db_thread();
process->file_thread();
process->process_launcher_thread();
process->cache_thread();
process->io_thread();
}

db_thread线程负责数据库处理,file_thread负责文件管理,cache_thread负责管理缓存。io_thread则负责管理进程间通信和所有I/O行为。

这其中,io_thread不仅负责Browser进程的I/O,而且其他Renderer的I/O请求也会通过进程间通信发送到这个线程,由该线程进行处理,最后把结果在返回给各个Renderer进程。各个线程的功能不一样,但设计模式是一样的,下面重点分析一下io_thread的初始化和执行流程。

线程的创建在BrowserProcessImpl的CreateIOThread中实现,代码如下:
void BrowserProcessImpl::CreateIOThread() {
DCHECK(!created_io_thread_ && io_thread_.get() == NULL);
created_io_thread_ = true;

PluginService::GetInstance();

#if defined(USE_X11)
// The lifetime of the BACKGROUND_X11 thread is a subset of the IO thread so
// we start it now.
scoped_ptrbase::Thread background_x11_thread(
new BrowserProcessSubThread(BrowserThread::BACKGROUND_X11));
if (!background_x11_thread->Start())
return;
background_x11_thread_.swap(background_x11_thread);
#endif

scoped_ptr thread(new IOThread);
base::Thread::Options options;
options.message_loop_type = MessageLoop::TYPE_IO;
if (!thread->StartWithOptions(options))
return;
io_thread_.swap(thread);
}

先创建一个IOThread的实例,然后设置此线程的类型为TYPE_IO,接着,调用StartWithOptions启动这个线程。

StartWithOptions函数首先是保存传递进来的Options,接着通过PlatformThread::Create来创建线程,这里PlatformThread类的作用是支持不同系统平台的线程的创建。然后调用startup_data.event.Wait()来等待此线程的消息循环的启动,这表明只有消息循环启动之后,整个函数才能返回。

在PlatformThread::Create很简单,调用系统APICreateThread,线程函数是ThreadFunc,传递给线程函数的参数就是IOThread对象本身的指针。

ThreadFunc也很简单,之后调用Thread的成员ThreadMain, 所以ThreadMain才是线程的主函数。

下面详细分析一下ThreadMain,首先定义一个MessageLoop类的对象,并把之前保存的类型赋予这个对象。接着调用IOThread的Init进行基本的初始化动作,然后调用startup_data_->event.Signal(),让线程处于未置信状态。最后调用MessageLoop的Run进入无限的消息循环,直到接到退出消息循环的命令,此时线程也要结束了。这是一般windows线程的常用方式,只不过chrome对其进行了一定的封装,并且把定义了几种不同的消息循环。

在MessageLoop中有一个枚举变量有如下定义:

enum Type {
TYPE_DEFAULT,
TYPE_UI,
TYPE_IO
};

可见总共有3种不同的消息循环。

MessageLoopForUI::Run(Dispatcher* dispatcher);

void MessageLoop::RunHandler()

猜你喜欢

转载自blog.csdn.net/hunter___/article/details/82804780