Chromium中的utility进程

有时候Chromium浏览器主进程需要做一些“危险”的事情,比如图片解码、文件解压缩。如果这些“危险”的操作发生了失败,会导致整个主进程发生异常崩溃,这是我们不愿意看到的。因此Chromium设计出了一个utility进程的机制。主进程临时需要做一些不方便的任务的情况下,可以启动一个utility进程来代替主进程执行,主进程与utility进程之间通过IPC消息来通信。我写一个收集电脑硬件信息的例子来介绍如何使用utility进程。

首先我们需要继承UtilityProcessHostClient创建一个自己的类HardwareProber。我们在HardwareProber里面处理与utility进程的IPC通信。在HardwareProbe里面我们会通过UtilityProcessHost::Create创建一个UtilityProcessHost,通过UtilityProcessHost的Send方法,我们可以向utility进程发送IPC消息。我们不用管理UtilityProcessHost的生命周期,所以持有UtilityProcessHost的WeakPtr即可。

UtilityProcessHost提供了一些接口:

  • SetExposedDir。在沙箱里暴露一个utility进程可以操作的目录。
  • DisableSandbox。禁用utility进程的沙箱。
  • ElevatePrivileges。提权utility进程。
  • SetEnv。设置utility进程的环境变量。

通常需要执行某个任务,然后启动一个utility进程。当任务完成,utility进程就退出。有时候我们需要做很多同样的事情,如果频繁的启动和退出utility进程,效率比较低。因此UtilityProcessHost还有个Batch模式,就是在一个utility进程里处理多个相同的任务。一般utility进程退出都是utility进程自己主动调用content::UtilityThread::Get()->ReleaseProcessIfNeeded()。如果在Batch模式下,那边则由主进程来控制utility进程的退出,需要调用StartBatchMode和EndBatchMode。

UtilityProcessHostClient还具有RefCountedThreadSafe属性。它的生命周期是当utility进程退出后,IPC断开了BrowserChildProcessHostImpl来销毁。所以我们也不用管理UtilityProcessHostClient对象生命周期。

主进程里面HardwareProber的IPC消息首先会发到utility进程的ChromeContentUtilityClient里面来。我们可以在ChromeContentUtilityClient里面处理消息,也可以继承UtilityMessageHandler创建一个HardwareProberHandler类来处理IPC消息。

HardwareProberHandler override OnMessageReceived方法来接受IPC消息,通过content::UtilityThread::Get()->Send()来发送消息,通过content::UtilityThread::Get()->ReleaseProcessIfNeeded()来退出utility进程。

《Chromium中的utility进程》有2个想法

    1. 例子就不分享了,Chromium代码在不断更新,现在IPC都要切换到Mojo,我的例子可能会过时。你可以搜Chromium中的代码,里面也很多应用到utility的场景,你可以参考那个。

发表评论

电子邮件地址不会被公开。 必填项已用*标注