Board logo

标题: 深入 HTML5 Web Worker 应用实践:多线程编程(1)简介 [打印本页]

作者: look_w    时间: 2018-10-18 16:48     标题: 深入 HTML5 Web Worker 应用实践:多线程编程(1)简介

HTML5 中工作线程(Web Worker)简介至 2008 年 W3C 制定出第一个 HTML5 草案开始,HTML5 承载了越来越多崭新的特性和功能。它不但强化了 Web 系统或网页的表现性能,而且还增加了对本地数据库等 Web 应用功能的支持。其中,最重要的一个便是对多线程的支持。在 HTML5 中提出了工作线程(Web Worker)的概念,并且规范出 Web Worker 的三大主要特征:能够长时间运行(响应),理想的启动性能以及理想的内存消耗。Web Worker 允许开发人员编写能够长时间运行而不被用户所中断的后台程序,去执行事务或者逻辑,并同时保证页面对用户的及时响应。本文深入 HTML5 多线程规范,讲述多线程实现原理、方法,同时以实例的形式讲解 HTML5 中多线程编程以及应用。
W3C 中的工作线程规范到目前为止已经定义了出了一系列公共接口,它允许 Web 程序开发人员去创建后台线程在他们的主页面中并发的运行脚本。这将使得线程级别的消息通信成为现实。
详解 HTML5 工作线程原理传统上的线程可以解释为轻量级进程,它和进程一样拥有独立的执行控制,一般情况下由操作系统负责调度。而在 HTML5 中的多线程是这样一种机制,它允许在 Web 程序中并发执行多个 JavaScript 脚本,每个脚本执行流都称为一个线程,彼此间互相独立,并且有浏览器中的 JavaScript 引擎负责管理。下面我们将详细讲解 HTML5 的工作线程原理。
工作线程与多线程编程在 HTML5 中,工作线程的出现使得在 Web 页面中进行多线程编程成为可能。众所周知,传统页面中(HTML5 之前)的 JavaScript 的运行都是以单线程的方式工作的,虽然有多种方式实现了对多线程的模拟(例如:JavaScript 中的 setinterval 方法,setTimeout 方法等),但是在本质上程序的运行仍然是由 JavaScript 引擎以单线程调度的方式进行的。在 HTML5 中引入的工作线程使得浏览器端的 JavaScript 引擎可以并发地执行 JavaScript 代码,从而实现了对浏览器端多线程编程的良好支持。
HTML5 中的 Web Worker 可以分为两种不同线程类型,一个是专用线程 Dedicated Worker,一个是共享线程 Shared Worker。两种类型的线程各有不同的用途。下面对这两种工作线程作了详细的说明和描述。
专用线程:Dedicated Worker共享线程 Shared Worker工作线程事件处理模型当工作线程被一个具有 URL 参数的构造函数创建的时候,它需要有一系列的处理流程来处理和记录它本身的数据和状态。下面我们给出了工作线程的处理模型如下(注:由于 W3C 中工作线程的规范依然在更新,您读到这篇文章的时候可能看到已不是最新的处理模型,建议参考 W3C 中的最新规范):
1. 创建一个独立的并行处理环境,并且在这个环境里面异步的运行下面的步骤。
2. 如果它的全局作用域是 SharedWorkerGlobalScope 对象,那么把最合适的应用程序缓存和它联系在一起。
3. 尝试从它提供的 URL 里面使用 synchronous 标志和 force same-origin 标志获取脚本资源。
4. 新脚本创建的时候会按照下面的步骤:
5. 启动线程监视器,关闭孤儿线程。
6. 对于挂起线程,启动线程监视器监视挂起线程的状态,即时在并行环境中更改它们的状态。
7. 跳入脚本初始点,并且启动运行。
8. 如果其全局变量为 DedicatedWorkerGlobalScope 对象,然后在线程的隐式端口中启用端口消息队列。
9. 对于事件循环,等待一直到事件循环列表中出现新的任务。
10. 首先运行事件循环列表中的最先进入的任务,但是用户代理可以选择运行任何一个任务。
11. 如果事件循环列表拥有存储 mutex 互斥信号量,那么释放它。
12. 当运行完一个任务后,从事件循环列表中删除它。
13. 如果事件循环列表中还有任务,那么继续前面的步骤执行这些任务。
14. 如果活动超时后,清空工作线程的全局作用域列表。
15. 释放工作线程的端口列表中的所有端口。
工作线程应用范围和作用域工作线程的全局作用域仅仅限于工作线程本身,即在线程的生命周期内有效。规范中 WorkerGlobalScope 接口代表了它的全局作用域,下面我们来看下这个接口的具体实施细节(WorkerGlobalScope 抽象接口)。
清单 5. WorkerGlobalScope 抽象接口代码
1
2
3
4
5
6
7
8
9
interface WorkerGlobalScope {
readonly attribute WorkerGlobalScope self;
readonly attribute WorkerLocation location;

void close();
          attribute Function onerror;
};
WorkerGlobalScope implements WorkerUtils;
WorkerGlobalScope implements EventTarget;




我们可以使用 WorkerGlobalScope 的 self 属性来或者这个对象本身的引用。location 属性返回当线程被创建出来的时候与之关联的 WorkerLocation 对象,它表示用于初始化这个工作线程的脚步资源的绝对 URL,即使页面被多次重定向后,这个 URL 资源位置也不会改变。
当脚本调用 WorkerGlobalScope 上的 close()方法后,会自动的执行下面的两个步骤:
1. 删除这个工作线程事件队列中的所有任务。
2. 设置 WorkerGlobalScope 对象的 closing 状态为 true (这将阻止以后任何新的任务继续添加到事件队列中来)。
工作线程生命周期工作线程之间的通信必须依赖于浏览器的上下文环境,并且通过它们的 MessagePort 对象实例传递消息。每个工作线程的全局作用域都拥有这些线程的端口列表,这些列表包括了所有线程使用到的 MessagePort 对象。在专用线程的情况下,这个列表还会包含隐式的 MessagePort 对象。
每个工作线程的全局作用域对象 WorkerGlobalScope 还会有一个工作线程的线程列表,在初始化时这个列表为空。当工作线程被创建的时候或者拥有父工作线程的时候,它们就会被填充进来。
最后,每个工作线程的全局作用域对象 WorkerGlobalScope 还拥有这个线程的文档模型,在初始化时这个列表为空。当工作线程被创建的时候,文档对象就会被填充进来。无论何时当一个文档对象被丢弃的时候,它就要从这个文档对象列举里面删除出来。
在工作线程的生命周期中,定义了下面四种不同类型的线程名称,用以标识它们在线程的整个生命周期中的不同状态:
由于 W3C 的 Web Worker 规范目前还是处于完善阶段,没有形成最终的规范,本文也将上面线程的四种不同状态的原文定义附在了后面。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0