WebWorker 工作线程

2024-05-02 17:32
文章标签 线程 工作 webworker

本文主要是介绍WebWorker 工作线程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

WebWorker H5工作线程

1、多线程的支持
2、三大主要特征:能够长时间运行、理想的启动性能、理想的内存消耗
3、允许在 Web 程序中并发执行多个 JavaScript 脚本,每个脚本执行流都称为一个线程,彼此间互相独立,并且有浏览器中的 JavaScript 引擎负责管理

工作线程与多线程编程

1、HTML5 中的 Web Worker 可以分为两种不同线程类型,一个是专用线程 Dedicated Worker,一个是共享线程 Shared Worker

专用线程:Dedicated Worker

1、创建线程:

在创建专用线程的时候,需要给 Worker 的构造函数提供一个指向 JavaScript 文件资源的 URL,这也是创建专用线程时 Worker 构造函数所需要的唯一参数。
示例代码:var worker = new Worker(‘dedicated.js’);

2、与一个专用线程通信

专用线程在运行的过程中会在后台使用 MessagePort 对象,而 MessagePort 对象支持 HTML5 中多线程提供的所有功能,例如:可以发送和接受结构化数据(JSON 等),传输二进制数据,并且支持在不同端口中传输数据等。
为了在页面主程序接收从专用线程传递过来的消息,我们需要使用工作线程的 onmessage 事件处理器
示例代码:worker.onmessage = function (event) { … };
向专用线程发数据:用postmessage方法

共享线程:Shared Worker

1、共享线程

定义方式:一、通过指向JavaScript脚本资源的URL来创建、二、通过显示的名称

2、共享线程的创建

创建共享线程可以通过使用 SharedWorker() 构造函数来实现,这个构造函数使用 URL 作为第一个参数,即是指向 JavaScript 资源文件的 URL,同时,如果开发人员提供了第二个构造参数,那么这个参数将被用于作为这个共享线程的名称。
示例代码:var worker = new SharedWorker(‘sharedworker.js’, ’ mysharedworker ’ );

3、与共享线程通信

共享线程的通信也是跟专用线程一样,是通过使用隐式的 MessagePort 对象实例来完成的。当使用 SharedWorker() 构造函数的时候,这个对象将通过一种引用的方式被返回回来。我们可以通过这个引用的 port 端口属性来与它进行通信。
发送消息与接收消息的代码:

// 从端口接收数据 , 包括文本数据以及结构化数据
1. worker.port.onmessage = function (event) { define your logic here... }; 
// 向端口发送普通文本数据
2. worker.port.postMessage('put your message here … '); 
// 向端口发送结构化数据
3. worker.port.postMessage({ username: 'usertext'; live_city: 
['data-one', 'data-two', 'data-three','data-four']});

第一个我们使用 onmessage 事件处理器来接收消息,第二个使用 postMessage 来发送普通文本数据,第三个使用 postMessage 来发送结构化的数据,这里使用了 JSON 数据格式

工作线程事件处理模型

当工作线程被一个具有 URL 参数的构造函数创建的时候,它需要有一系列的处理流程来处理和记录它本身的数据和状态。
工作线程的处理模型如下:
1. 创建一个独立的并行处理环境,并且在这个环境里面异步的运行下面的步骤。
2. 如果它的全局作用域是 SharedWorkerGlobalScope 对象,那么把最合适的应用程序缓存和它联系在一起。
3. 尝试从它提供的 URL 里面使用 synchronous 标志和 force same-origin 标志获取脚本资源。
4. 新脚本创建的时候会按照下面的步骤:
创建这个脚本的执行环境。
使用脚本的执行环境解析脚本资源。
设置脚本的全局变量为工作线程全局变量。
设置脚本编码为 UTF-8 编码。
5. 启动线程监视器,关闭孤儿线程。
6. 对于挂起线程,启动线程监视器监视挂起线程的状态,即时在并行环境中更改它们的状态。
7. 跳入脚本初始点,并且启动运行。
8. 如果其全局变量为 DedicatedWorkerGlobalScope 对象,然后在线程的隐式端口中启用端口消息队列。
9. 对于事件循环,等待一直到事件循环列表中出现新的任务。
10. 首先运行事件循环列表中的最先进入的任务,但是用户代理可以选择运行任何一个任务。
11. 如果事件循环列表拥有存储 mutex 互斥信号量,那么释放它。
12. 当运行完一个任务后,从事件循环列表中删除它。
13. 如果事件循环列表中还有任务,那么继续前面的步骤执行这些任务。
14. 如果活动超时后,清空工作线程的全局作用域列表。
15. 释放工作线程的端口列表中的所有端口。

工作线程API
类库和脚本的访问和引入

对于类库和脚本的访问和引入,规范中规定可以使用 WorkerGlobalScope 对象的 importScripts(urls) 方法来引入网络中的脚本资源。

当用户调用这个方法引入资源的时候会执行下面的步骤来完成这个操作:
1. 如果没有给 importScripts 方法任何参数,那么立即返回,终止下面的步骤。
2. 解析 importScripts 方法的每一个参数。
3. 如果有任何失败或者错误,抛出 SYNTAX_ERR 异常。
4. 尝试从用户提供的 URL 资源位置处获取脚本资源。
5. 对于 importScripts 方法的每一个参数,按照用户的提供顺序,获取脚本资源后继续进行其它操作。

工作导航器对象

在 HTML5 中, WorkerUtils 接口的 navigator 属性会返回一个工作导航器对象(WorkerNavigator),这个对象定义并且代表了用户代理(即 Web 客户端)的标识和状态。因此,用户和 Web 脚本开发人员可以在多线程开发过程中通过这个对象来取得或者确定用户的状态。

工作导航器对象(WorkerNavigator)

WorkerUtils 抽象接口的 navigator 属性会返回一个 WorkerNavigator 用户接口,用于用户代理的识别的状态标识。我们来看下 WorkerNavigator 接口的定义。

WorkerNavigator 接口定义

接口定义代码
interface WorkerNavigator {};
WorkerNavigator implements NavigatorID;
WorkerNavigator implements NavigatorOnLine;

工作线程(Web Worker)应用与实践

应用场景:使用工作线程做后台数值(算法)计算

工作线程最简单的应用就是用来做后台计算,而这种计算并不会中断前台用户的操作。下面我们提供了一个工作线程的代码片段,用来执行一个相对来说比较复杂的任务:计算两个非常大的数字的最小公倍数和最大公约数。

在这个例子中,我们在主页面中创建一个后台工作线程,并且向这个工作线程分配任务(即传递两个特别大的数字),当工作线程执行完这个任务时,便向主页面程序返回计算结果,而在这个过程中,主页面不需要等待这个耗时的操作,可以继续进行其它的行为或任务。

我们把这个应用场景分为两个主要部分,一个是主页面,可以包含主 JavaScript 应用入口,用户其它操作 UI 等。另外一个是后台工作线程脚本,即用来执行计算任务。

主程序页面代码:

<!DOCTYPE HTML> 
<html> 
<head> 
<title> 
Background Worker Application Example 1: Complicated Number Computation 
</title> 
</head> 
<body> 
<div> 
The least common multiple and greatest common divisor is: 
<p id="computation_results">please wait, computing … </p> 
</div> <script>var worker = new Worker('numberworker.js'); 
worker.postMessage("{first:347734080,second:3423744400}"); worker.onmessage = function (event) 
{ document.getElementById(' computation_result').textContent = event.data; 
}; </script>
</body> 
</html>

后台工作线程代码

/** * This worker is used to calculate * the least common multiple * and the greatest common divisor */ onmessage = function (event) { var first=event.data.first; var second=event.data.second; calculate(first,second); }; /* * calculate the least common multiple * and the greatest common divisor */ function calculate(first,second) { //do the calculation work var common_divisor=divisor(first,second); var common_multiple=multiple(first,second); postMessage("Work done! " + 
"The least common multiple is "+common_divisor +" and the greatest common divisor is "+common_multiple); } /** * calculate the greatest common divisor * @param number * @param number * @return */ function divisor(a, b) { if (a % b == 0) { return b; } else { return divisor(b, a % b); } } /** * calculate the least common multiple * @param number * @param number * @return */ function multiple( a,  b) { var multiple = 0; multiple = a * b / divisor(a, b); return multiple; }

在主程序页面中,我们使用 Worker()构造函数创建一个新的工作线程,它会返回一个代表此线程本身的线程对象。接下来我们使用这个线程对象与后台脚本进行通信。线程对象有两个主要事件处理器:postMessage 和 onmessage 。postMessage 用来向后台脚本发送消息,onmessage 用以接收从后台脚本中传递过来的消息。

在后台工作线程代码片段中,我们定一个两个 JavaScript 函数,一个是 function divisor:用以计算最大公约数,一个是 function multiple:用以计算最小公倍数。同时工作线程的 onmessage 事件处理器用以接收从主页面中传递过来的数值,然后把这两个数值传递到 function calculate 用以计算。当计算完成后,调用事件处理器 postMessage,把计算结果发送到主页面。

IN THE END

HTML5 Web Worker 的多线程特性为基于 Web 系统开发的程序人员提供了强大的并发程序设计功能,它允许开发人员设计开发出性能和交互更好的富客户端应用程序。本文不仅仅详细讲述 HTML5 中的多线程规范。同时,也以几种典型的应用场景为例,以实例的形式讲解 HTML5 中多线程编程以及应用,为用户提供了详细而全面的参考价值,并且指导开发人员设计和构建更为高效和稳定的 Web 多线程应用。

这篇关于WebWorker 工作线程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/954788

相关文章

工作常用指令与快捷键

Git提交代码 git fetch  git add .  git commit -m “desc”  git pull  git push Git查看当前分支 git symbolic-ref --short -q HEAD Git创建新的分支并切换 git checkout -b XXXXXXXXXXXXXX git push origin XXXXXXXXXXXXXX

嵌入式方向的毕业生,找工作很迷茫

一个应届硕士生的问题: 虽然我明白想成为技术大牛需要日积月累的磨练,但我总感觉自己学习方法或者哪些方面有问题,时间一天天过去,自己也每天不停学习,但总感觉自己没有想象中那样进步,总感觉找不到一个很清晰的学习规划……眼看 9 月份就要参加秋招了,我想毕业了去大城市磨练几年,涨涨见识,拓开眼界多学点东西。但是感觉自己的实力还是很不够,内心慌得不行,总怕浪费了这人生唯一的校招机会,当然我也明白,毕业

线程的四种操作

所属专栏:Java学习        1. 线程的开启 start和run的区别: run:描述了线程要执行的任务,也可以称为线程的入口 start:调用系统函数,真正的在系统内核中创建线程(创建PCB,加入到链表中),此处的start会根据不同的系统,分别调用不同的api,创建好之后的线程,再单独去执行run(所以说,start的本质是调用系统api,系统的api

husky 工具配置代码检查工作流:提交代码至仓库前做代码检查

提示:这篇博客以我前两篇博客作为先修知识,请大家先去看看我前两篇博客 博客指路:前端 ESlint 代码规范及修复代码规范错误-CSDN博客前端 Vue3 项目开发—— ESLint & prettier 配置代码风格-CSDN博客 husky 工具配置代码检查工作流的作用 在工作中,我们经常需要将写好的代码提交至代码仓库 但是由于程序员疏忽而将不规范的代码提交至仓库,显然是不合理的 所

java线程深度解析(六)——线程池技术

http://blog.csdn.net/Daybreak1209/article/details/51382604 一种最为简单的线程创建和回收的方法: [html]  view plain copy new Thread(new Runnable(){                @Override               public voi

java线程深度解析(五)——并发模型(生产者-消费者)

http://blog.csdn.net/Daybreak1209/article/details/51378055 三、生产者-消费者模式     在经典的多线程模式中,生产者-消费者为多线程间协作提供了良好的解决方案。基本原理是两类线程,即若干个生产者和若干个消费者,生产者负责提交用户请求任务(到内存缓冲区),消费者线程负责处理任务(从内存缓冲区中取任务进行处理),两类线程之

java线程深度解析(四)——并发模型(Master-Worker)

http://blog.csdn.net/daybreak1209/article/details/51372929 二、Master-worker ——分而治之      Master-worker常用的并行模式之一,核心思想是由两个进程协作工作,master负责接收和分配任务,worker负责处理任务,并把处理结果返回给Master进程,由Master进行汇总,返回给客

java线程深度解析(二)——线程互斥技术与线程间通信

http://blog.csdn.net/daybreak1209/article/details/51307679      在java多线程——线程同步问题中,对于多线程下程序启动时出现的线程安全问题的背景和初步解决方案已经有了详细的介绍。本文将再度深入解析对线程代码块和方法的同步控制和多线程间通信的实例。 一、再现多线程下安全问题 先看开启两条线程,分别按序打印字符串的

java线程深度解析(一)——java new 接口?匿名内部类给你答案

http://blog.csdn.net/daybreak1209/article/details/51305477 一、内部类 1、内部类初识 一般,一个类里主要包含类的方法和属性,但在Java中还提出在类中继续定义类(内部类)的概念。 内部类的定义:类的内部定义类 先来看一个实例 [html]  view plain copy pu

未来工作趋势:零工小程序在共享经济中的作用

经济在不断发展的同时,科技也在飞速发展。零工经济作为一种新兴的工作模式,正在全球范围内迅速崛起。特别是在中国,随着数字经济的蓬勃发展和共享经济模式的深入推广,零工小程序在促进就业、提升资源利用效率方面显示出了巨大的潜力和价值。 一、零工经济的定义及现状 零工经济是指通过临时性、自由职业或项目制的工作形式,利用互联网平台快速匹配供需双方的新型经济模式。这种模式打破了传统全职工作的界限,为劳动