[ZZ]翻译chromium开发文档之-Inter-process Communication,进程间通信

本文主要是介绍[ZZ]翻译chromium开发文档之-Inter-process Communication,进程间通信,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Inter-process Communication

进程间通信


Overview

Chromium has a multi-process architecture which means that we have a lot of processes communicating with each other. Our main inter-process communication primitive is the named pipe. A named pipe is allocated for each renderer process for communication with the browser process. The pipes are used in asynchronous mode to ensure that neither end is blocked waiting for the other.


总览

Chromium有一个多进程的架构,这意味着我们有许多进程间通信.我们主要使用命名管道来做进程间通信.每一个渲染进程都创建一个命名管道,用来和浏览器主进程通信.这些管理都是异步模式的,用来保证它们不会阻塞在对其它管道的等待上.


IPC in the browser

Within the browser, communication with the renderers is done in a separate I/O thread. Messages to and from the views then have to be proxied over to the main thread using a ChannelProxy. The advantage of this scheme is that resource requests (for web pages, etc.), which are the most common and performance critical messages, can be handled entirely on the I/O thread and not block the user interface. These are done through the use of a ChannelProxy::MessageFilter which is inserted into the channel by the RenderProcessHost. This filter runs in the I/O thread, intercepts resource request messages, and forwards them directly to the resource dispatcher host. See Multi-process Resource Loading for more information on resource loading.


浏览器进程中的IPC

在浏览器进程中,与渲染进程的通信是在一个单独的IO线程中完成的[译注:这里的IO线程是用来做通信,而不是读写磁盘的].从视图中发送或者是接收的消息需要使用一个ChannelProxy来代理.这种机制的好处就是,资源请求(如网页),是最常见也是与性能息息相关的消息,可以完全在IO线程中处理而不影响用户界面.通过使用ChannelProxy::messageFilter可以做到这一点.它被RenderProcessHost插入到一个通道中.这个filter在IO线程中运行,拦截资源请求消息,然后把消息发给ResourceDispather宿主.(参见Multi-process Resource Loading获取关于资源加载的更多信息).


IPC in the renderer

Each renderer also has a thread that manages communication (in this case, the main thread), with the rendering and most processing happening on another thread (see the diagram in multi-process architecture). Most messages are sent from the browser to the WebKit thread through the main renderer thread and vice-versa. This extra thread is to support synchronous renderer-to-browser messages (see "Synchronous messages" below).


渲染进程中的IPC

每一个渲染进程同样也有一个线程来管理通信(在主线程中),主要处理渲染和大部分在其它线程上做的处理(能见multi-process architecture文章中的图).浏览器主进程通过渲染进程的主线程发送大部分消息到WebKit线程中,或者正好相反.这个额外的线程用来支持异步的renderer-to-browser消息(见下面的"异步消息").


Messages

Types of messages

We have two primary types of messages: "routed" and "control." Routed messages are specific to a page, and will be routed to the view representing that page using the identifier for that view. For example, messages telling the view to paint, or notifications to display a context menu are routed messages.


消息

消息类型

我们有两种最根本的消息类型:"routed"和"control".Routed消息用于一个网页,使用一个ID连接到响应这个网页的视图上.举个例子,消息告诉视图要绘制屏幕,或者是提示要显示一个上下文菜单,这就是routed消息.


Control messages are not specific to a given view and will be handled by the RenderProcess (renderer) or the RenderProcessHost (browser). For example, requests for resources or to modify the clipboard are not view-specific so are control messages.


Control消息不指定到一个视图上,被RenderProcess(渲染进程)或者是RenderProcessHost(浏览器主进程)处理.例如,请求资源或者是对剪切簿做操作就是视图无关的,也就是Control消息.


Independent of the message type is whether the message is sent from the browser to the renderer, or from the renderer to the browser. Messages sent from the browser to the renderer are called View messages because they are being sent to the RenderView. Messages sent from the renderer to the browser are called ViewHost messages because they are being sent to the RenderViewHost. You will notice the messages defined in render_messages_internal.h are separated into these two categories.


与消息类型无关的是,消息如何从浏览器主进程发送到渲染进程,或者是从渲染进程发送到浏览器主进程.从浏览器主进程发送到渲染进程的消息被称为View消息,因为它们被发送到RenderView. 从渲染进程发送到浏览器主进程的消息被称为ViewHost消息,因为它们被发送到RenderViewHost。你会看到render_messages_internal.h中定义的消息被分成这两种。


Plugins also have separate processes. Like the render messages, there are PluginProcess messages (sent from the browser to the plugin process) and PluginProcessHost messages (sent from the plugin process to the browser). These messages are all defined in plugin_messages_internal.h. The automation messages (for controlling the browser from the UI tests) are done in a similar manner.


插件同样有单独的进程。与渲染进程消息类似,同样也有PluginProcess消息(从主浏览器进程发送到插件进程)和PluginProcessHost消息(从插件进程到浏览器主进程)。这些消息都定义在plugin_messages_internal.h头文件中。自动消息(UI测试中用来控制浏览器)的收发也是一样的。


Declaring messages

Special macros are used to declare messages. The messages sent between the renderer and the browser are all declared in render_messages_internal.h. There are two sections, one for "View" messages sent to the renderer, and one for "ViewHost" messages sent to the browser.


To declare a message from the renderer to the browser (a "ViewHost" message) that is specific to a view ("routed") that contains a URL and an integer as an argument, write:


声明一个消息

声明消息需要使用特别的宏。浏览器主进程和渲染进程间的消息都在plugin_messages_internal.h中声明。它们分成两部分,一种叫"View",发往渲染进程,另一种叫"ViewHost",发往浏览器主进程。


声明一个从渲染进程发送到浏览器主进程的消息(或者是"ViewHost"消息),消息是与一个视图相关的("routed"),包含了一个URL和一个整数,写法如下:


IPC_MESSAGE_ROUTED2(ViewHostMsg_MyMessage, GURL, int)


To declare a control message from the browser to the renderer (a "View" message) that is not specific to a view ("control") that contains no parameters, write:


声明一个从浏览器主进程发送到渲染进程的coltrol消息(或者是"View"消息),消息是与福星无关的,不包含参数,写法如下:


IPC_MESSAGE_CONTROL0(ViewMsg_MyMessage)


Pickling values


Parameters are serialized and de-serialized to message bodies using the ParamTraits template. Specializations of this template are provided for most common types in ipc_message_utils.h. If you define your own types, you will also have to define your own ParamTraits specialization for it.


使用ParamTraits模型将参数序列化和反序列化到消息主体。提供类型来特化这个模板,常见的类型位于ipc_message_utils.h。如果你定义了自己的类型,你也需要定义自己的ParamTraits特化。


Sometimes, a message has too many values to be reasonably put in a message. In this case, we define a separate structure to hold the values. For example, for the ViewMsg_Navigate message, the ViewMsg_Navigate_Params structure is defined in render_messages.h. That file also defines the ParamTraits specializations for the structures.


有时候,一个消息有过的参数要放入消息中。在这种情况下,我们定义了一个单独的结构来保存这些值。举个例子,对ViewMsg_Navigate消息来说,render_messages.h头文件中定义了ViewMsg_Navigate_Params 结构。这个头文件同样定义了对这个结构的ParamTraits特化。


Sending messages

You send messages through "channels" (see below). In the browser, the RenderProcessHost contains the channel used to send messages from the UI thread of the browser to the renderer. The RenderWidgetHost (base class for RenderViewHost) provides a Send function that is used for convenience.


发送消息

通过"channels"发送消息(见下文)。在浏览器中,RenderProcessHost 包含用来发送来自浏览器UI线程的消息的通道(channel),这些消息发往渲染进程。RenderWidgetHost(RenderViewHost的基类)提供一个Send函数简化操作。


Messages are sent by pointer and will be deleted by the IPC layer after they are dispatched. Therefore, once you can find the appropriate Send function, just call it with a new message:


消息用指针的形式发送,在它们派发后被IPC层删除。因此,当你找到了合适的的Send函数,只要用一个新消息调用它就可以了。


Send(new ViewMsg_StopFinding(routing_id_));


Notice that you must specify the routing ID in order for the message to be routed to the correct View/ViewHost on the receiving end. Both the RenderWidgetHost (base class for RenderViewHost) and the RenderWidget (base class for RenderView) have routing_id_ members that you can use.


要注意的是,你必须指定一个routing ID,用来使消息能够被路由[译注:或者关联]到接收端正确的View/ViewHost。RenderWidgetHost(RenderViewHost的基类)和RenderWidget(RenderView的基类)都包含routing_id_ 成员,你可以使用它们来做routing ID。


Handling messages

Messages are handled by implementing the IPC::Channel::Listener interface, the most important function on which is OnMessageReceived. We have a variety of macros to simplify message handling in this function, which can best be illustrated by example:


处理消息

实现IPC::Channel::Listener接口来处理消息,最重要的函数是OnMessageReceived。我们有多种宏来简化这个函数中的消息处理,举个例子是最好不过的了:


MyClass::OnMessageReceived(const IPC::Message& message) {

IPC_BEGIN_MESSAGE_MAP(MyClass, message)

    // Will call OnMyMessage with the message. The parameters of the message will be unpacked for you.

    IPC_MESSAGE_HANDLER(ViewHostMsg_MyMessage, OnMyMessage) 

    ...

    IPC_MESSAGE_UNHANDLED_ERROR() // This will throw an exception for unhandled messages.

IPC_END_MESSAGE_MAP()

}


// This function will be called with the parameters extracted from the ViewHostMsg_MyMessage message.

MyClass::OnMyMessage(const GURL& url, int something) {

...

}

You can also use IPC_DEFINE_MESSAGE_MAP to implement the function definition for you as well. In this case, do not specify a message variable name, it will declare a OnMessageReceived function on the given class and implement its guts.


你也可以使用IPC_DEFINE_MESSAGE_MAP来实现函数的定义。在这种情况下,不需要指定消息变量名,它会在指定的类上声明一个OnMessageReceived 函数,实现函数内容。


Other macros:


其它宏:


IPC_MESSAGE_FORWARD: This is the same as IPC_MESSAGE_HANDLER but you can specify your own class to send the message to, instead of sending it to the current class.

IPC_MESSAGE_FORWARD(ViewHostMsg_MyMessage, some_object_pointer, SomeObject::OnMyMessage)

IPC_MESSAGE_HANDLER_GENERIC: This allows you to write your own code, but you have to unpack the parameters from the message yourself:

IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_MyMessage, printf("Hello, world, I got the message."))


Security considerations

You must be very careful when unpacking messages in the browser. Since the renderer is sandboxed, one of the easiest ways to get out of the sandbox is to take advantage of insecure message unpacking. All parameters must be carefully validated and never trusted. Be particularly careful about signedness errors.


安全考虑

在浏览器中解包消息时你必须十分小心。因为渲染进程使用了沙箱技术,脱离沙箱的最简单的方法是利用不安全的消息解包。所有的参数必须小心地验证并且不被信任。注意一下无符号错误。


Channels

IPC::Channel (defined in chrome/common/ipc_channel.h) defines the methods for communicating across pipes. IPC::SyncChannel provides additional capabilities for synchronously waiting for responses to some messages (the renderer processes use this as described below in the "Synchronous messages" section, but the browser process never does).


通道

IPC::Channel (定义在chrome/common/ipc_channel.h)定义了通过管道通信的成员函数。IPC::SyncChannel 提供了附加的同步等待某些消息回应的功能(渲染进程像在下面""Synchronous messages"描述的那样使用它,但是浏览器进程却没有)。


Channels are not thread safe. We often want to send messages using a channel on another thread. For example, when the UI thread wants to send a message, it must go through the I/O thread. For this, we use a IPC::ChanelProxy. It has a similar API as the regular channel object, but proxies messages to another thread for sending them, and proxies messages back to the original thread when receiving them. It allows your object (typically on the UI thread) to install a IPC::ChannelProxy::Listener on the channel thread (typically the I/O thread) to filter out some messages from getting proxied over. We use this for resource requests and other requests that can be handled directly on the I/O thread. RenderProcessHost installs a ResourceMessageFilter object that does this filtering.


通道不是线程安全的。我们经常想要使用通道发送消息到另一个线程。举个例子,当UI线程想要发送一个消息,它必须通过I/O线程[注:IO线程是用来通信的,读写磁盘要用file线程]。我们使用 IPC::ChanelProxy来做这个工作,它有和普通channel对象相似的API,但是代理发送到其它进程的消息,也代理当接收到消息时,将消息返回到原始发送的线程。它允许你的对象(在UI线程中)安装一个IPC::ChannelProxy::Listener在channel线程(在IO线程上)上来过滤一些消息。我们使用它来做资源请求或者是其它可以直接在IO线程上处理的请求。RenderProcessHost安装一个ResourceMessageFilter对象来做消息过滤。


Synchronous messages

Some messages should be synchronous from the renderer's perspective. This happens mostly when there is a WebKit call to us that is supposed to return something, but that we must do in the browser. Examples of this type of messages are spell-checking and getting the cookies for JavaScript. Synchronous browser-to-renderer IPC is disallowed to prevent blocking the user-interface on a potentially flaky renderer.


同步消息

从渲染进程的角度来看,有一些消息应该是同步的。这经常发生在,当WebKit调用希望返回一些东西时,但是这些东西我们需要在浏览器主进程中完成。例如这种消息是:拼写检查,为JavaScript获取cookies。同步的broser-to-render IPC不允许潜在的用户界面阻塞。


Danger: Do not handle any synchronous messages in the UI thread! You must handle them only in the I/O thread. Otherwise, the application might deadlock because plug-ins require synchronous painting from the UI thread, and these will be blocked when the renderer is waiting for synchronous messages from the browser.


危险性:不要在UI线程中处理任何同步消息!你必须在IO线程中处理它们。否则应用程序可能会死锁,因为插件请求同步绘制,当渲染进程在等待浏览器主进程的同步消息时,而这些请求将被阻塞。


Declaring synchronous messages

Synchronous messages are declared using the IPC_SYNC_MESSAGE_* macros. These macros have input and return parameters (non-synchronous messages lack the concept of return parameters). For a control function which takes two input parameters and returns one parameter, you would append 2_1 to the macro name to get:


声明同步消息

同步消息使用IPC_SYNC_MESSAGE_* 宏来声明。这些宏有输入和返回参数(异步消息没有返回参数的概念)。对于一个clntrol函数,它带有两个输入参数和一个返回参数,你需要添加2_1到宏名字上:


IPC_SYNC_MESSAGE_CONTROL2_1(SomeMessage, // Message name

                            GURL, //input_param1

                            int, //input_param2

                            std::string); //result


Likewise, you can also have messages that are routed to the view in which case you would replace "control" with "routed" to get IPC_SYNC_MESSAGE_ROUTED2_1. You can also have 0 input or return parameters. Having no return parameters is used when the renderer must wait for the browser to do something, but needs no results. We use this for certain printing and clipboard operations.


同样的,你可以使用关联到视图的消息,在这种情况下,你可以用"routed"替换"control"来得到IPC_SYNC_MESSAGE_ROUTED2_1。你可以拥有0个输入参数或者是输出参数。没有返回参数用于渲染进程必须等待浏览器进程做完某些事情,但是不需要结果。我们使用它来做某些打印和剪切簿操作。


Issuing synchronous messages

When the WebKit thread issues a synchronous IPC request, the request object (derived from IPC::SyncMessage) is dispatched to the main thread on the renderer through a IPC::SyncChannel object (the same one is also used to send all asynchronous messages). The SyncChannel will block the calling thread when it receives a synchronous message, and will only unblock it when the reply is received.


发出一个同步消息

当WebKit线程发出一个同步IPC请求,这个请求对象(继承自IPC::SyncMessage)通过IPC::SyncChannel 对象(用于发送所有的同步消息)发送到浏览进程的主线程中。SyncChannel将阻塞调用线程直到它接收到一个回应。


While the WebKit thread is waiting for the synchronous reply, the main thread is still receiving messages from the browser process. These messages will be added to the queue of the WebKit thread for processing when it wakes up. When the synchronous message reply is received, the thread will be un-blocked. Note that this means that the synchronous message reply can be processed out-of-order.


当WebKit线程在等待同步消息的回应时,主线程仍然在接收来自浏览器主进程的消息。这些消息被加入到WebKit线程的队列中,以便它唤醒时处理。当接收到同步消息的应答时,线程被解锁。这意味着同步消息应答可以被无序处理。


Synchronous messages are sent the same way normal messages are, with output parameters being given to the constructor. For example:


同步消息像普通消息一样被发送,没有输出参数指定给构造函数,例如。


const GURL input_param("http://www.google.com/");

std::string result;

RenderThread::current()->Send(new MyMessage(input_param, &result));

printf("The result is %s/n", result.c_str());


Handling synchronous messages

Synchronous messages and asynchronous messages use the same IPC_MESSAGE_HANDLER, etc. macros for dispatching the message. The handler function for the message will have the same signature as the message constructor, and the function will simply write the output to the output parameter. For the above message you would add


处理同步消息

同步消息和异步消息使用相同的IPC_MESSAGE_HANDLER,等等的宏。宏用来发送消息。这个用于处理消息的函数与消息创建者有着同样的特征,函数只是简单地把输入写到输入参数中。在上面的消息里你可能添加:


IPC_MESSAGE_HANDLER(MyMessage, OnMyMessage)

to the OnMessageReceived function, and write:

void RenderProcessHost::OnMyMessage(GURL input_param, std::string* result) {

*result = input_param.spec() + " is not available";

}

====================================================

感谢原作者的辛勤劳动!感谢!

官方原文:: http://www.chromium.org/developers/design-documents/inter-process-communication

本文ref :: http://hi.baidu.com/shihuap/blog/item/55f69ddfad74af144854034f.html

你可以自由传播此文章但请注明译者

huapingsmith@gmail.com

这篇关于[ZZ]翻译chromium开发文档之-Inter-process Communication,进程间通信的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/294362

相关文章

Eclipse+ADT与Android Studio开发的区别

下文的EA指Eclipse+ADT,AS就是指Android Studio。 就编写界面布局来说AS可以边开发边预览(所见即所得,以及多个屏幕预览),这个优势比较大。AS运行时占的内存比EA的要小。AS创建项目时要创建gradle项目框架,so,创建项目时AS比较慢。android studio基于gradle构建项目,你无法同时集中管理和维护多个项目的源码,而eclipse ADT可以同时打开

Python应用开发——30天学习Streamlit Python包进行APP的构建(9)

st.area_chart 显示区域图。 这是围绕 st.altair_chart 的语法糖。主要区别在于该命令使用数据自身的列和指数来计算图表的 Altair 规格。因此,在许多 "只需绘制此图 "的情况下,该命令更易于使用,但可定制性较差。 如果 st.area_chart 无法正确猜测数据规格,请尝试使用 st.altair_chart 指定所需的图表。 Function signa

基于Java医院药品交易系统详细设计和实现(源码+LW+调试文档+讲解等)

💗博主介绍:✌全网粉丝10W+,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码+数据库🌟 感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人  Java精品实战案例《600套》 2023-2025年最值得选择的Java毕业设计选题大全:1000个热

WDF驱动开发-WDF总线枚举(一)

支持在总线驱动程序中进行 PnP 和电源管理 某些设备永久插入系统,而其他设备可以在系统运行时插入和拔出电源。 总线驱动 必须识别并报告连接到其总线的设备,并且他们必须发现并报告系统中设备的到达和离开情况。 总线驱动程序标识和报告的设备称为总线的 子设备。 标识和报告子设备的过程称为 总线枚举。 在总线枚举期间,总线驱动程序会为其子 设备创建设备对象 。  总线驱动程序本质上是同时处理总线枚

工程文档CAD转换必备!在 Java 中将 DWG 转换为 JPG

Aspose.CAD 是一个独立的类库,以加强Java应用程序处理和渲染CAD图纸,而不需要AutoCAD或任何其他渲染工作流程。该CAD类库允许将DWG, DWT, DWF, DWFX, IFC, PLT, DGN, OBJ, STL, IGES, CFF2文件、布局和图层高质量地转换为PDF和光栅图像格式。 Aspose API支持流行文件格式处理,并允许将各类文档导出或转换为固定布局文件格

JavaWeb系列六: 动态WEB开发核心(Servlet) 上

韩老师学生 官网文档为什么会出现Servlet什么是ServletServlet在JavaWeb项目位置Servlet基本使用Servlet开发方式说明快速入门- 手动开发 servlet浏览器请求Servlet UML分析Servlet生命周期GET和POST请求分发处理通过继承HttpServlet开发ServletIDEA配置ServletServlet注意事项和细节 Servlet注

手把手教你入门vue+springboot开发(五)--docker部署

文章目录 前言一、前端打包二、后端打包三、docker运行总结 前言 前面我们重点介绍了vue+springboot前后端分离开发的过程,本篇我们结合docker容器来研究一下打包部署过程。 一、前端打包 在VSCode的命令行中输入npm run build可以打包前端代码,出现下图提示表示打包完成。 打包成功后会在前端工程目录生成dist目录,如下图所示: 把

Sapphire开发日志 (十) 关于页面

关于页面 任务介绍 关于页面用户对我组工作量的展示。 实现效果 代码解释 首先封装一个子组件用于展示用户头像和名称。 const UserGrid = ({src,name,size,link,}: {src: any;name: any;size?: any;link?: any;}) => (<Box sx={{ display: "flex", flexDirecti

ROS2从入门到精通4-4:局部控制插件开发案例(以PID算法为例)

目录 0 专栏介绍1 控制插件编写模板1.1 构造控制插件类1.2 注册并导出插件1.3 编译与使用插件 2 基于PID的路径跟踪原理3 控制插件开发案例(PID算法)常见问题 0 专栏介绍 本专栏旨在通过对ROS2的系统学习,掌握ROS2底层基本分布式原理,并具有机器人建模和应用ROS2进行实际项目的开发和调试的工程能力。 🚀详情:《ROS2从入门到精通》 1 控制插

JavaWeb 学习笔记 spring+jdbc整合开发初步

JdbcTemplate类是Spring的核心类之一,可以在org.springframework.jdbc.core中找到它。JdbcTemplate类在内部已经处理数据库的建立和释放,可以避免一些常见的错误。JdbcTemplate类可直接通过数据源的应用实例化,然后在服务中使用,也可在xml配置中作为JavaBean应用给服务使用直接上一个实例步骤1.xml配置 <?xml version