进程:Process/Tsak 操作系统(OS)为正在运行的程序分配的CPU资源的最小单位。拥有独立的地址空间。
用网页打开.html程序便运行到内存
线程:Thead:CPU执行的最小单位;同一个进程下的所有线程,共享进程的地址空间 进程内部执行代码基本单位
线程之间是没有层级关系的,他们之间协同完成工作。在整个进程完成工作之后,其中的线程会被销毁,释放资源。
一个进程由多个线程组成 某个线程出错 不影响整个进程的工作
一个chrome浏览器进程内部,最多可以使用6个并发的线程,"并发"向web服务器发起HTTP请求,以获取所需资源---资源请求线程
还有一个线程负责所有内容绘制到浏览器,执行js任务---UI主线程
虽然,每一个window只有一个js引擎,但是浏览器是事件驱动的、异步的、多线程的。js要处理的事件队列,是浏览器维护的
线程和进程的共同点:
都包含三个状态,就绪、阻塞、运行。通俗的讲,阻塞就是资源未到位,等待资源中。就绪,就是资源到位了,但是CPU未到位,还在运行其他。
线程的好处
1、在一个程序中,多个线程可以同步或者互斥并行完成工作,简化了编程模型;
2、线程较进程来讲,更轻;
3、在一个进程内部,一个线程阻塞后,不会影响其他线程,提高了CPU的利用率。
事件轮询
有很多任务需要执行,三种解决方法:
(1)排队。因为一个进程一次只能执行一个任务,只好等前面的任务执行完了,再执行后面的任务。
(2)新建进程。使用fork命令,为每个任务新建一个进程。
(3)新建线程。因为进程太耗费资源,所以如今的程序往往允许一个进程包含多个线程,由线程去完成任务。
绿色部分是程序的运行时间,红色部分是等待时间。可以看到,由于I/O操作很慢,所以这个线程的大部分运行时间都在空等I/O操作的返回结果。这种运行方式称为"同步模式"(synchronous I/O)或"堵塞模式"(blocking I/O)
采用多线程,同时运行多个任务时(右图),说明多线程不仅占用多倍的系统资源,也闲置多倍的资源
事件轮询
主线程的绿色部分,表示运行时间,而橙色部分表示空闲时间。每当遇到I/O的时候,主线程就让Event Loop线程去通知相应的I/O程序,然后接着往后运行,所以不存在红色的等待时间。等到I/O程序完成操作,Event Loop线程再把结果返回主线程。主线程就调用事先设定的回调函数,完成整个任务。
多出了橙色的空闲时间,所以主线程得以运行更多的任务,这就提高了效率。这种运行方式称为"异步模式"(asynchronous I/O)或"非堵塞模式"(non-blocking mode)。
Node.js
不是真正意义上的js,他是借用了js语法实现的,达到真正意义的非阻塞服务端语言。但是他的运行机制,也是事件轮询 (Event Loop)
web worker的使用
多线程就是一个进程中有多个线程。在进程内部进行线程间的切换,由于每个线程执行的时间片很短,所以在感觉上是并行的。
假设1.js文件工作起来非常耗时(假设要3s执行完)
解决方案:创建一个并发执行的新线程,让它来执行耗时js 任务
<script>new Worker("1.js");</script>
浏览器不允许Worker线程操作DOM/BOM对象 所以,类似JQuery的代码不能Worker
Worker线程可以给UI主线程发数据
Worker:(发) 6.js中
postMessage(stringMsg);
UI:(收)
var w = new Worker("6.js");
w.onmessage = function(e){ //message接收数据事件
e.data //data是传过来的数据
}
UI主线程可以给Worker线程发数据
UI:(发)
var w = new Worker("6.js");
w.postMessage(str);
Worker:(收) 6.js中
onmessage = function(e){e.data}