js进程和线程的区别

JavaScript08

js进程和线程的区别,第1张

一、线程和进程基本概念

进程:操作系统分配的占有CPU资源的最小单位。拥有独立的地址空间。

线程:安排CPU执行的最小单位。同一个进程下的所有线程,共享进程的地址空间。

简单讲,计算机就像工厂,进程是个大车间,计算机内部有很多个这样的大车间。线程是工人,每一个车间里的工人至少有一个。

为什么这么画呢?有点一个挨一个的效果呢?是因为以前我就老是疑惑进程或者线程运行时到底是并行?还是串行?

其实,在单CPU或单核的情况下,宏观上无论是进程也好,线程也罢,都是并行的。而在微观下,某一个具体的时刻,他们实际上都是串行的。在多CPU或多核的情况下,才是真正意义的并行。

二、线程和进程的关系、通性

关系:进程中包含着至少一个线程。在进程创建之初,就会包含一个线程,这个线程会根据需要,调用系统库函数去创建其他线程。但需要注意的是,这些线程之间是没有层级关系的,他们之间协同完成工作。在整个进程完成工作之后,其中的线程会被销毁,释放资源。

通性:都包含三个状态,就绪、阻塞、运行。通俗的讲,阻塞就是资源未到位,等待资源中。就绪,就是资源到位了,但是CPU未到位,还在运行其他。

三、线程的好处

既然,线程和进程是存在通性的,那么为什么操作系统还要设置线程这个单位,那就说说线程的几点好处:

1、在一个程序中,多个线程可以同步或者互斥并行完成工作,简化了编程模型;

2、线程较进程来讲,更轻;

3、线程虽然微观并行。但是,在一个进程内部,一个线程阻塞后,会执行这个进程内部的其他线程,而不是整体阻塞。从某种意义上,提高了CPU的利用率。

四、市面上的通用叫法

单线程与多线程,都指在一个进程内的单和多。不要笑我,之前真的不懂。心中那只小羊驼,奔过来,跑过去。还抬起了傲娇的眼睛,看了我一眼,呵呵~~~

五、javaScript单线程执行机制

1、 首先解释下,单线程和多线程。

什么是单线程?单线程就是一个进程中只有一个线程。程序顺序执行,前面的执行完,才会执行后面的程序。

什么是多线程?多线程就是一个进程中只有多个线程。在进程内部进行线程间的切换,由于每个线程执行的时间片很短,所以在感觉上是并行的。

2、那么为什么感觉上javaScript是多线程?而且还支持AJAX异步呢?AJAX是真正的异步吗?

先说明,从哪里可以得出javaScript是单线程。比如你页面一上来就alert(“hello world~”);只要你不关闭这个对话框,后续的js代码就不会再执行。因为,单线程就是这样一步一步的顺次执行,前面不执行完,后面不会执行。也就是说,在具体的某一时刻,只有一段代码在执行。

可是,JavaScript明明可以处理各种触发事件,感觉上是异步多线程啊。其实,它的原理是这样的,JavaScript单线程的执行浏览器的一个事件队列,要执行的函数和触发事件的回调函数都被放在这个队列中。比如,我点击率一下按钮,之后又将浏览器缩小了,那么这两个事件的回调函数就会顺次地被放在当前执行的“函数”之后,再一一执行。

那么,既然JavaScript是单线程,那么如何维护这个函数队列呢,他分身无术啊。这时候,就需要知道,浏览器可不是单线程。虽然,每一个window只有一个js引擎,但是浏览器是事件驱动的、异步的、多线程的。

浏览器内部有一个事件轮询(event loop),是一个大的内部消息循环,会轮询大的消息队列,并执行。也就是js要处理的事件队列,是浏览器维护的。

浏览器至少有四个线程(不同浏览器会有差异): js引擎线程、界面渲染线程、浏览器事件触发线程、http请求线程。

其实,到这里就说的很明白了。但是,又想到了延时函数(setTimeout)的例子,感觉上,因为没有阻塞执行,会感觉是异步,其实并不是。只是,js在执行到延时函数时,会触发浏览器的定时器,到设置时间,浏览器再将这个函数放入执行的函数队列,再由JavaScript引擎执行。都是在浏览器空闲了才会执行。

关于AJAX的异步,是真正的异步。同样的道理,在调用AJAX的时候,浏览器会开辟一个新的线程,去处理这个请求,得到响应后,如果这个请求有回调,会将这个回调再放入事件队列中。再由JavaScript引擎执行。

3、关于JavaScript的阻塞

浏览器虽然是多线程,但是由于JavaScript具有阻塞特性,无论外链还是内嵌脚本,在浏览器执行解释js脚本的时候,浏览器是不会去做别的事情的,比如渲染页面,而是直到js下载并执行完毕。

这样,js脚本的下载、解释执行,会反该页面的继续绘制,给用户带来不良的体验。所以,要对其优化,有如下几点:

a、将<script>内嵌和外链,在可以的情况下,放在<body>底部。注:对于css,浏览器是并行下载

b、在页面onload后,加载js

c、html5 <script>标签的defer属性,在页面加载完成后下载

d、使用创建<script>标签的方式,在页面加载完成后添加进去。

注:解决阻塞就是一句话,先让页面渲染完,再加载js。

六、Node.js单线程执行机制

脑子就像有问题一样。js都是单线程的了,node.js就是js实现的,还能是多线程?!!呵呵哒~

Node.js其实还不是真正意义上的js,他是借用了js语法实现的,达到真正意义的非阻塞服务端语言。但是他的运行机制,也是事件轮询 (Event Loop)。

Nodejs的主进程是单线程的,但它有多线程处理方案(更准备来说是多进程方案),即主进程开启不同的子进程,主进程接收所有请求,然后将分发给其它不同的nodejs子进程处理。

它一般有两种实现:

Nodejs 的 cluster模式 用的就是第一种实现,它使用一个主线程 master 和多个子线程 worker ,形成一个集群,通过主线程来向子线程分发请求。cluster 实现了对 child_process 的封装,通过 fork 方法创建子进程的方式实现了多进程模型。

http 和 cluster 、 process 都是 nodejs 的内置模块,不需要额外安装

实现过程大概是这样的: cluster 模块应用 child_process 来创建子进程,子进程通过复写掉 cluster._getServer 方法,从而在 server.listen 来保证只有主进程监听端口,主子进程通过 IPC 进行通信,其次主进程根据平台或者协议不同,应用两种不同模块( round_robin_handle.js 和 shared_handle.js )进行请求分发给子进程处理。

PM2是后台进程管理器,是多进程方案的一个成熟应用,可以帮助管理和保持应用程序在线。

全局安装: npm install pm2@latest -g

它的使用也非常简单:

PM2对nodejs应用,可以根据系统自动实现负载均衡: pm2 start http-server.js -i max

我们肯定不想每次启动时,都要手动输入一堆指令,所以我们可以将这些配置统一使用配置文件来管理,注意js文件名必须是 xxx.config.js ,我这里用 ecosystem.config.js :

apps 数组中,可以放置多个对象,对应多个文件执行不同的配置

执行配置: pm2 start ecosystem.config.js --env dev

可以看到在启动后,桌面上生成了流水和错误日志:

一,打开子进程窗口;首先自己写好自己的vue页面,我这里写好的页面的名字是 zchildern;然后把页面引入路由里面,把路由的模式改成哈希模式1,在要触发的vue页面事件中这样写:const ipc = require('electron').ipcRendereripc.send('add')2,在background.js中接受触发的事件;首先引入 ipcMain;接收:(图下面是代码)const path = require('path')const url = require('url')const winURL = process.env.NODE_ENV === 'development'? 'http://192.168.2.184:3000': `file://${__dirname}/index.html`// 上边这段代码主要是用来解决vue路由访问页面的问题,端口号是vue启动的默认端口号,如果有需要可以自行修改ipcMain.on('add',()=>{let newwin = new BrowserWindow({width: 350,maxWidth:350, //配置窗口的最大尺寸minWidth:350, //配置窗口的最小尺寸height: 500,maxHeight:500,frame:false,modal: true, //配置子窗口是模态窗口movable:false,//窗口能否可以被移动;true or false,默认值为 trueparent: win, //win是主窗口webPreferences: {nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,webSecurity: false, // 是否禁用浏览器的跨域安全特性}})newwin.loadURL(winURL + '#/zchildren')// newwin.loadURL(path.join('file:',__dirname,'zchildren'))//new.html是新开窗口的渲染进程newwin.on('closed',()=>{newwin = null})})