chrome进程间通信

chrome设计时采用的一种方法是多进程技术(不仅限于此,也有其他方式),其中涉及到一个重要的问题就是进程间通信。

one tab, one process

可以从操作系统任务管理器以及CHROME自带的任务管理器可以看出,确实每个tab页,一个进程。

 

进程模型

浏览器进程负责进程管理以及进程通信。在浏览器进程中,有其他所有进程的标记,每个标记对应一个线程。浏览器对相关标记的操作,会被封装成消息,并发送给对应的Process来处理。
渲染进程嵌入WebKit来解析, 渲染和处理网页及网络应用。

 

 

进程间通信

在WINDOS平台,chrome采用命名管道进行进程间通信。

在ipc_channel.cc代码中有如下注释(Channels are implemented using named pipes on Windows)
服务器:

 

管道创建:CreateNamedPipe
等待链接:ConnectNamedPipe(类似于SOCKET中的LISTEN)
数据发送:WriteFile
数据接收:ReadFile

客户端

管道连接:CreateFile或者CallNamedPipe
数据发送:WriteFile
数据接收:ReadFile

 

CHROME进程间通信实现:

通信结构图

 

 

chrome中对进程间通信进行封装实现:CHANEL。
相关代码:ipc_channel.h ipc_sender.h ipc_reader.h ipc_listener.h ipc_channel_win.h及其CPP文件。

bool Channel::ChannelImpl::CreatePipe(const IPC::ChannelHandle &channel_handle,
                                      Mode mode);

 

 

若FLAG为MODE_SERVER_FLAG,有如下代码:命名管道的创建

 const DWORD open_mode = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
                            FILE_FLAG_FIRST_PIPE_INSTANCE;
    pipe_name = PipeName(channel_handle.name, &client_secret_);
    pipe_ = CreateNamedPipeW(pipe_name.c_str(),
                             open_mode,
                             PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
                             1,
                             Channel::kReadBufferSize,
                             Channel::kReadBufferSize,
                             5000,
                             NULL);

 

若FLAG为MODE_CLIENT_FLAG,则为管道连接

pipe_name = PipeName(channel_handle.name, &client_secret_);
    pipe_ = CreateFileW(pipe_name.c_str(),
                        GENERIC_READ | GENERIC_WRITE,
                        0,
                        NULL,
                        OPEN_EXISTING,
                        SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION |
                        FILE_FLAG_OVERLAPPED,
                        NULL);

消息发送:

bool Channel::ChannelImpl::Send(Message* message) {
};

 

 

从管道中读取消息:根据管道句柄,设置数据缓冲区以及数据大小,直接读取即可。

Channel::ChannelImpl::ReadState Channel::ChannelImpl::ReadData(
    char* buffer,
    int buffer_len,

  DWORD bytes_read = 0;
  BOOL ok = ReadFile(pipe_, buffer, buffer_len,
                     &bytes_read, &input_state_.context.overlapped);
}

 

 

总结:

常用的IPC方式
1. SOCKET:该方法不管是单机还是分布于不同计算机内的进程,都可以通信。SOCKET是全双工的。
2. 管道(Pipe):注:管道是单向的,如果要起到双向的结果,需要建立两条管道。
创建管道的程序成为管道服务器,连接到管道的程序成为管道客户机。
3. 共享内存:多个进程可以共同访问同一块内存。
4. 信号量、互斥量:该内核对象可以在进程间共享。起到进程间通信的效果

5. 消息队列:进程间可以通过消息队列进行通信。将消息发送到对方进程的消息队列中。

注:参考
1.《Google Chrome 浏览器架构解析及相关特性分析》
2. http://lihuan623.blog.163.com/blog/static/1385958452010449734597/

未经允许不得转载:Cooders'S Blog » chrome进程间通信