深入研究Electron的主进程和渲染进程

 

主进程“和“渲染进程”是Electron的两个核心的概念。

如果你之前做的是浏览器端JavaScript开发,多进程的概念对你来说可能是一个新的领域。

最初对我来说,这绝对是一个思维方式的转变,使用多进程可能意味着我们需要在开发过程中做出跟之前不同的设计抉择。

为什么Electron具有这种多进程架构?主进程职责是什么?渲染进程的职责是什么?它们之间如何实现通信?

首先,我们这里所说的“进程”是什么?

一个操作系统级别的进程,或者如Wikipedia所述,它是“正在执行的计算机程序的实例”。

我们启动一个Electron应用程序,然后在macOS中检查“活动监视器”,则可以看到与该程序关联的进程数。

 

“ Electron”是主进程,一个“ Electron Helper”是GPU进程,另一个“ Electron Helpers”是渲染进程。

 

这些进程中的每一个彼此并发运行。这里要记住的最重要的一点是,进程的内存和资源是相互隔离的。

举例来说,假设我有一个模块,该模块可以保存我的主进程和渲染进程所需的某些状态:

 

 

 

 

如果我在渲染进程中增加1,则渲染进程中的计数将为1,但在主进程中仍为0。

这两个进程不共享内存或状态。实际上,该模块有两个实例在运行。

为什么要多个进程?

此架构决策源自Chromium。Chromium在单独的进程中运行每个选项卡(即webContents实例),因此,如果一个选项卡遇到致命错误,则不会关闭整个应用程序。从这个意义上说,“ Chromium像操作系统一样构建,使用多个OS进程将网站彼此隔离,并与浏览器本身隔离。” 因此,每个进程“在其自己的地址空间中运行,由操作系统调度,并且可以单独失败”。当有人一步小心地写了一个无限循环,然后关闭正在运行的选项卡,而不是整个浏览器。这种体系结构要感谢这种弹性。还有安全原因。Chromium的多进程体系结构文档非常有趣:https://www.chromium.org/developers/design-documents/multi-process-architecture

主进程

主进程负责创建和管理BrowserWindow实例以及各种应用程序事件。它还可以执行诸如注册全局快捷方式,创建系统菜单和对话框,响应自动更新事件等操作。应用程序的入口点将指向将在主进程中执行的JavaScript文件。主进程以及所有node.js模块中都提供了一部分Electron API(请参见下图)。

 

docs声明:“基本规则是:如果模块与GUI或低级系统相关,则它应仅在主进程l中可用。” (请注意,此处的GUI是指本机GUI,而不是Chromium呈现的基于HTML的UI)。这是为了避免潜在的内存泄漏问题。

渲染进程

渲染过程负责运行应用程序的用户界面,换句话说,就是作为webContents实例的网页。渲染进程中提供了所有DOM API,node.js API和Electron API的子集(请参见下图)。

我曾经将BrowserWindow与渲染进程混合在一起。在窗口中包含webContents实例之前,实际上不会创建渲染进程。这有点挑剔,但我认为这很重要,并且知道它会导致更坚实的概念基础。另外,一个或多个WebContent可以位于一个窗口中。等等,一个或多个?是的,因为单个窗口可以承载多个Web视图,并且每个Web视图都是其自己的webContents实例和渲染进程。因此,例如,如果您的页面中包含2个Web视图,则将有3个渲染进程-一个用于托管2个Web视图的父级,然后一个用于每个Web视图。话虽如此,除非您要运行远程网页,否则无需使用Web视图,因此不必太在意该细节。

 

 

 

上图显示了每种进程中可用的Electron API。您还可以看到Node.js API全局可用,而渲染进程中只有DOM / Browser API。

 

 

如何在进程之间进行通信?

Electron使用进程间通信(IPC)在进程之间进行通信-与Chromium相同。

IPC有点像在网页和iframe或webWorker之间使用postMessage。

一般来说,发送的消息会带有频道名称和一些其他信息。

IPC可以在渲染进程和主进程之间双向通信。IPC默认情况下是异步的,但也具有同步API(例如Node.js中的fs)。

Electron还为提供了远程模块,例如,您可以使用主处理模块,就像Menu渲染器中可用的一样。

不需要进行手动IPC调用,但实际上是在幕后,您是通过同步IPC调用向主进程发出命令。

使用devtron模块,我们可以观察到使用远程模块时发生的所有IPC调用。同步IPC调用可能会有性能缺陷。在许多情况下,可能还不错。

 

 

 

 

remote用于打开对话框时,会发生多个同步IPC调用。

使用ipc或远程API的代码非常简单。一个基本的示例可以在这里找到: ccnokes / electron-tutorials-小样本电子应用程序的集合

有没有一个方法是主进程和渲染进程都支持的?

是的,可以通过remote模块访问主进程API,例如:

 

 

 

IPC是否在底层使用了某些网络协议(例如tcp,http或更疯狂的东西)?

不。Chromium的IPC文档指出,它使用“命名管道”作为IPC的基础工具。命名管道比网络协议可以提供更快,更安全的通信。

“命名管道”类似于“无名管道”,当您执行类似操作时使用ls | grep foo。命名管道很有趣,

您可以在此处查看示例:https : //github.com/ccnokes/node-fifo-example

那么我在哪里进行CPU密集型工作?

我曾经认为 主进程 是“繁重工作”的理想之地,因为它不会阻塞UI。

实际上,这是错误的—如果我们在主进程中执行CPU密集型工作,它将锁定所有渲染进程。

因此,CPU密集型任务应在单独的进程中运行-而不是任何包含UI的现有渲染进程或主进程。

其实,最简单的方法是使用Electron-remote。Electron-remote非常棒,并且具有渲染进程任务池,该任务池将跨多个进程拆分和平衡作业。

这是一个简单的例子:

 

 

 

 

 

 

在这段代码中electron remore 最多创建4个BrowserWindow实例,所有这些实例都需要您的模块并运行它,然后协调进程之间的来回通信。

 

 

附:IPC通信的几种方式

 

数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M字节之间
共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到。
通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。
资源共享:多个进程之间共享同样的资源。为了作到这一点,需要内核提供锁和同步机制。
进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。

linux常用的进程间的通讯方式

(1)、管道(pipe):管道可用于具有亲缘关系的进程间的通信,是一种半双工的方式,数据只能单向流动,允许一个进程和另一个与它有共同祖先的进程之间进行通信。

(2)、命名管道(named pipe):命名管道克服了管道没有名字的限制,同时除了具有管道的功能外(也是半双工),它还允许无亲缘关系进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。

(3)、信号(signal):信号是比较复杂的通信方式,用于通知接收进程有某种事件发生了,除了进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。

(4)、消息队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺

(5)、共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。

(6)、内存映射:内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。

(7)、信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。

(8)、套接字(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。

原文地址:https://www.cnblogs.com/onesea/p/15308246.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


这篇文章主要讲解了“electron打包中的坑如何解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“electron...
这篇文章主要介绍“electron打包的坑如何解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“electron打包的坑如何...
这篇文章主要为大家分析了VSCode中如何调试Electron应用的主进程代码的相关知识点,内容详细易懂,操作细节合理,具有一定参考价值。如果感兴趣的话,不妨跟着跟...
这篇“如何在VSCode上调试Electron应用的主进程代码”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价
vue-cli+electron一种新的脚手架(vue-electron)vue-electron主要业务逻辑都放在src下的renderer文件夹内,和之前的vue-cli搭建项目流程没有任何区别 GIT地址:https://github.com/SimulatedGREG/electron-vue 搭建项目:1.全局安装脚手架:npminstall--globalvue-cli
1、首先成功安装Node.js。2、配置好环境变量path,参加上一篇博客《NodeJs安装》3、全局安装electron,并测试。如下图
相关代码:https://github.com/WozHuang/Barrage-helper/blob/master/src/main/index.dev.js在SPA逐渐成为构建优秀交互体验应用的主流方式后,使用Electron开发跨平台的软件是一个优秀的解决方案。下面简单介绍一下Electron-vue安装vue-devtool的方式。安装步骤下载vue-de
前言本人是做java开发的(菜鸟),做web项目的朋友们基本上都会遇到同样一个,永远不知道客户会怎么样使用,或者说永远不知道客户会用什么浏览器打开我们做出来的应用,就算你跟他说明了一定得用某某某浏览器打开,还是有人会用别的浏览器打开,这种情况通常我们会去做适配(前端),最近公司有需求
electron-builder是将electron做的桌面应用打包成安装包的插件。一、安装使用yarn安装,使用npm安装的有问题(没有尝试),先安装yarn工具。npminstall-gyarn安装electron-builderyarnaddelectron-builder--save-dev二、配置在package.json 中配置"build":{
来源:https:/ewsn.net/say/electron-asar.html 在electron中,asar是个特殊的代码格式。asar包里面包含了程序猿编写的代码逻辑。默认情况下,这些代码逻辑,是放置在resource/app目录下面的,明文可见,这样的话,也就有了代码加密(asar打包)的需求 asar如何解密加密?electron的asar的
 字体图标丢失问题解决方案 重新打包文件npmrunbuild再次运行electron 
<img:src="item.headUrl"alt=""class="contact-head":onerror="morenImage">data(){return{morenImage:'this.src="static/image/head.png"',//默认头像}}
在electron-vue中使用了字体图标,但是打包成.exe文件后图标不显示,路劲问题把字体图标放到static目录下就可以了,静态图片也一样我原来放在其它地方不行改到static目录就可以了
//设置登录cookiesetCookie(name,value){varDays=30;varexp=newDate();vardate=Math.round(exp.getTime()/1000)+Days*24*60*60;constcookie={url:this.webApi,name:name,value:value,e
vue部分cnpminstall-gvue-clivueinitsimulatedgreg/electron-vuemy-projectelectron下载失败解决办法:单独设置electron为淘宝镜像,npmconfigsetelectron_mirrorhttps:/pm.taobao.org/mirrors/electron/yarnconfigsetelectron_mirrorhttps:/pm.taobao.org
原始的方式打包下载对应的版本号的ReleaseElectron然后把对应的项目方便整理成这样的目录结构(Windows下)node_modules重新安装,不然可能启动失败把整文件夹给别人就可以了如果想改名子可以用改名工具rcedit应用程序打包成一个文件为了缓解windows路径名过长的问题(就
窗口间通信的问题electron窗口通信比nwjs要麻烦的多electron分主进程和渲染进程,渲染进程又分主窗口的渲染进程和子窗口的渲染进程主窗口的渲染进程给子窗口的渲染进程发消息1234567891011subWin.webContents.on('dom-ready', () => {    subWin.webCo
按照上一个问题here,我有一个使用Electron平台和Javascript的桌面应用程序,我使用以下方法将HTML5画布转换为JPEG:<aid="download"download="Path.jpg">DownloadJPG</a>然后,functiondownload(){vardt=canvas.toDataURL('image/jpeg');this.href
一.什么是Electron?它和NW.js的区别是什么?Electron是GitHub开发的桌面应用开发框架,它支持使用HTML、CSS、JavaScript来构建跨平台的桌面应用。Electron和NW.js(NW.js是什么可以百度下)的区别是:1.整合Chromium和Node.js的方式不同。在NW.js中,Chromium是直接被打补丁打进去
1.打开父子模态创建,<button@click="showModalHandler">父子模态窗口</button>/enderer渲染器中主注册事件showModalHandler(){ipcRenderer.send("child-down-modal");}//主进程中触发事件/***父子模态窗口*/letchildDownModal;ipcMain.on(&#