线程与进程
-**进程:**程序的一次执行,它占有一片独有的内存空间,可以通过windows任务管理器查看进程
-**线程:**是进程内的一一个独立执行单元,是程序执行的一个完整流程,是CPU的最小的调度单元
-关系
一个进程至少有一个线程(主)
程序是在某个进程中的某个线程执行的
一个进程中也可以同时运行多个线程,我们会说程序是多线程运行的
一个进程内的数据可以供其中的多个线程直接共享
多个进程之间的数据是不能直接共享的
线程池(thread pool):保存多个线程对象的容器,实现线程对象的反复利用
4. 浏览器运行是单进程还是多进程?
- 有的是单进程
- firefox
- 老版IE
- 有的是多进程
- chrome
- 新版IE
- 如何查看浏览器是否是多进程运行的呢?
- 任务管理器==>进程
- 浏览器运行是单线程还是多线程?
- 都是多线程运行的
浏览器内核模块组成
-什么是浏览器内核?
- 支持浏览器运行的最核心的程序
-不同的浏览器可能不太一样 - Chrome, Safari: webkit
- firefox: Gecko
- IE: Trident
- 360,搜狗等国内浏览器: Trident + webkit
-主线程 - js引擎模块:负责js程序的编译与运行
- html,css文档解析模块:负责页面文本的解析
- DOM/CSS模块:负责dom/css在内存中的相关处理
*布局和渲染模块:负责页面的布局和效果的绘制(内存中的对象)
-分线程
*定时器模块:负责定时器的管理
*事件响应模块:负责事件的管理
*网络请求模块:负责Ajax请求
js线程
-
js是单线程执行的(回调函数也是在主线程)
为什么js要用单线程模式, 而不用多线程模式?- JavaScript的单线程,与它的用途有关。只能有一个线程更新界面
- 作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。
- 这决定了它只能是单线程,否则会带来很复杂的同步问题
-
H5提出了实现多线程的方案: Web Workers
*只能是主线程更新界面
定时器问题:
*定时器并不真正完全定时
*如果在主线程执行了一个长时间的操作,可能导致延时才处理
alert会暂停定时器
事件处理机制(图)
-代码分类
*初始化执行代码:包含绑定dom事件监听,设置定时器,发送ajax请求的代码
*回调执行代:处理回调逻辑
-js引擎执行代码的基本流程:
*初始化代码===>回调代码
-模型的2个重要组成部分:
*事件管理模块
*回调队列
-模型的运转流程
*执行初始化代码,将事件回调函数交给对应模块管理
*当事件发生时,管理模块会将回调函数及其数据添加到回调列队中
*只有当初始化代码执行完后(可能要一定时间), 才会遍历读取回调队列中的回调函数执行
H5 Web Workers
- H5规范提供了js分线程的实现, 取名为: Web Workers
- 相关API
- Worker: 构造函数, 加载分线程执行的js文件
- Worker.prototype.onmessage: 用于接收另一个线程的回调函数
- Worker.prototype.postMessage: 向另一个线程发送消息
- 不足
- worker内代码不能操作DOM(更新UI)
- 不能跨域加载JS
- 不是每个浏览器都支持这个新特性
//单线程计算
<script type="text/javascript">
//1 1 2 3 5 8
function fibonacci(n){
return n<=2? 1 : fibonacci(n-1) + fibonacci(n-2)
}
//fibonacci()
var input = document.getElementById("number")
var btn = document.getElementById("btn")
btn.οnclick=function(){
var number = input.value
var result = fibonacci(number)
alert(result)
}
</script>
<input type="text" id="number" value="30">
<button id="btn">计算fibonacci值</button>
<--计算得到fibonacci数列中第n个数的值
在主线程计算: 当位数较大时, 会阻塞主线程, 导致界面卡死
在分线程计算: 不会阻塞主线程
-->
<script type="text/javascript">
//1 1 2 3 5 8
var input = document.getElementById("number")
var btn = document.getElementById("btn")
btn.οnclick=function(){
var number = input.value
//创建一个worker对象
var worker = new Worker('worker.js');
//绑定接收消息的监听
worker.onmessage = function(event){
console.log('主线程接收分线程返回的数据'+event.data)
alert(event.data)
}
//向分线程发送消息
worker.postMessage(number)
console.log('主线程向分线程发送数据'+number)
}
</script>
function fibonacci(n){
return n<=2? 1 : fibonacci(n-1) + fibonacci(n-2)
}
var onmessage = function(event){
var number = event.data
console.log("分线程接受到主线程发送的数据:"+number)
//计算
var result = fibonacci(number)
console.log(this)
postMessage(result)//worker.postMessage(result) 不能这么写
console.log('分线程向主线程返回数据:'+result)//comsole是浏览器的方法
//alert(result) alert是window的方法,在分线程不能调用,分线程看不到
//分线程中的全局对象不再是window,所以不会更新界面
}