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

关于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_ptr 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()

你可能感兴趣的:(Chrome网络部分源代码分析)