web worker在WebKit中的实现机制

web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。这是HTML5的一个标准;实现上讲,浏览器为wokrer启动了新的线程,从而实现了异步操作的功能;

下面是woker的一个简单例子,在html页面中,以worker.js为源文件,创建了名为“worker”的Worker对象,通过worker.postMessage()接口向worker线程发送消息; worker线程将JSON格式化传递的两个数据相加后,再通过postMessage()接口将消息发送回页面js运行的主线程; 主线程再在onMessage()函数中处理woker线程发来的消息;

main.html

<html>
  <head>
  <script type="text/javascript">
    var worker = new Worker(’worker.js’);
    var obj = {"first":1, "second":2};
    worker.postMessage(obj);
    worker.onmessage = function (event) {
      alert(event.data);
    }

    function postMsg(){
      if (worker)
        worker.postMessaage(obj);
    }
  </script>
  </head>
  <body>
     <button onclick="postMsg()">post</button>
  </body>
</html>

worker.js

 onmessage = function (event)
 {
    var data = event.data;
   var first=data.first;
   var second=data.second;
   handleTask(first,second);
 }; 

 function  handleTask(a, b)
  {
    var out = a + b;
    postMessage("Worker Done! out = " + out);
  }

WebKit加载并执行js的流程简单分成以下几步:

1. 执行到"var worker = new Worker(‘worker.js‘)“时,在内核中构造WebCore::JSWorker对象(JSBbindings层)以及对应的WebCore::Worker对象(WebCore模块);

2.  构造JSWorker对象的过程中,根据初始化的url地址"worker.js"发起异步加载的流程;

3.  执行worker.postMessage(),向worker线程发送JSON格式化的消息数据; 因为这个时候,worker线程还没有创建,所以消息数据放在一个临时消息队列中;

4. worker.js异步加载完成后,创建并启动worker线程,并将临时消息队列中的消息数据copy到woker对应的WorkerRunLoop的消息队列中;

5. worker线程创建完成后,开始处理WorkerRunLoop的消息队列中所保存的消息;

6. woker线程发送消息到主线程;

7. 主线程消息worker线程发送的消息,执行onMessage();

当然如果,在经过一轮消息来回后,我们通过例子中的button按钮来异步触发消息发送,那么步骤3的执行会有区别; 这个时候因为worker线程已经创建,所以消息会直接添加到WorkerRunLoop的消息队列中;

为了搞清楚整个实现机制,我们先来看一下WebKit内部worker相关的类, 其中Worker对应主页面JS中的‘worker‘对象(主线程中),而DedicatedWorkerThread表示worker线程; WorkerMessagingProxy关联了Worker对象与worker线程,从而实现主线程与worker线程之间的消息中转; DedicatedWorkerThread通过WorkerScriptController控制worker.js文件中的脚本在worker线程中的执行;浏览器会为worker线程创建一个独立的虚拟机环境(VM);

下面来看一下详细流程:

1. worker.js的异步加载过程如下图,加载是在创建WebCore::JSWorker和WebCore::Worker对象的时候发起的,并且是异步加载的流程,不会阻塞后续JS的执行,这也是为什么首次调用worker.postMessage()的时候,会出现worker线程还没有创建的情况;

2. worker线程的创建如下图所示。可以看出,当worker.js加载完成后,WebKit会通过中转对象WorkerMessagingProxy创建DedicatedWorkerThread对象,并启动WorkerThread; WorkerMessagingProxy保持DedicatedWorkerThread对象的指针;

3.  主线程向worker线程发送消息的流程如下,当js执行到"worker.postMessage()“时,最终会通过JS主线程虚拟机映射到JSWorker::postMessage()函数,并通过中转对象WorkerMessagingProxy将消息添加到worker的消息队列; 如果worker线程在发送消息的时候,还没有创建,我们看到有个m_queueEarlyTasks对象会临时保存当前消息,并在worker线程创建后再转移到正式的消息队列中; 否则,直接将消息添加到WorkerRunLoop管理的正式消息队列中;

4. worker线程中处理消息的流程如下,这就是worker.js中开始执行”onmessage()”的流程; 我们可以看到DedicatedWorkThread对象在自己的线程环境下的runLoop取出消息队列中的数据执行;而执行是通过EventTarget::dispatchEvent()分发并fire一个"message"类型的事件来实现的;

5. 下图是在worker线程中发送消息的流程,也是通过WorkerMessagingProxy来进行中传,最后会触发Document::postTask()函数,该函数实际上将Document::didReceiveTask()函数抛到主线程上去执行;

6. 下图是main线程上处理消息的流程, Document::didReceiveTask()在主线程上开始执行,最终也是通过dispatch并fire一个"message"类型的事件实现消息的处理;

, 

所以总得来讲,woker的机制是通过中转对象实现消息的传递,再通过"message"事件完成消息的处理;

----------------------------------------------------------------------

原文地址:http://blog.csdn.net/codigger/article/details/40581343

----------------------------------------------------------------------

时间: 2024-08-09 19:52:40

web worker在WebKit中的实现机制的相关文章

Web worker 与JS中异步编程的对比

0.从一道题说起 var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert('end'); 问,以上代码何时alert"end"呢? 测试一下:答案是:永远都不会alert. 解析:JavaScript引擎是单线程的,事件触发排队等候.所有任务按照触发时间先后排队处理. 上例中,排队的顺序状态是: | var t=true ; | while(t){}; | alert('end'); | 在

关于Web Worker你必须知道的7件事

介绍 通过使用Web Worker, 我们可以在浏览器后台运行Javascript, 而不占用浏览器自身线程.Web Worker可以提高应用的总体性能,并且提升用户体验.如果你想在自己的Web应用中使用Web Worker, 不妨来了解一下有关Web Worker的7件事. 1. Web Worker 可以让你在后台运行Javascript 一般来说Javascript和页面的UI会共用一个线程,所以当点击一个按钮开始运行Javascript后,在这段代码运行完毕之前,页面是无法响应用户操作的

HTML5新增的一些属性和功能之八——web Worker

Web Workers 为什么用web workers? 浏览器的原理中决定了页面打开只有一个主线程--UI渲染线程,如果线程中有耗时的程序(js)会阻塞线程,使得页面中其他的UI无法渲染,我们一般把js文件放在body结束之前,或者优化算法复杂度.但是根本上解决还是线程的问题.在HTML5中新增了web Workers的方法,用来解决JavaScript多线程的问题.把一些耗时的程序放在单独的js中,和浏览器的UI渲染线程同步执行. 如何用: 1.首先把需要单独执行的js代码单独放在一个js文

Web Worker是什么

.Web Worker是什么 Web Worker 是HTML5标准的一部分,这一规范定义了一套 API,它允许一段JavaScript程序运行在主线程之外的另外一个线程中.Web Worker 规范中定义了两类工作线程,分别是专用线程Dedicated Worker和共享线程 Shared Worker,其中,Dedicated Worker只能为一个页面所使用,而Shared Worker则可以被多个页面所共享,本文示例为专用线程Dedicated Worker. 1.1 API快速上手 使

JS线程模型&amp;Web Worker

js线程模型 客户端javascript是单线程,浏览器无法同时运行两个事件处理程序 设计为单线程的理论是,客户端的javascript函数必须不能运行太长时间,否则会导致web浏览器无法对用户输入做出响应.这也是为什么Ajax的API都是异步的,以及为什么客户端Javascript不能使用一个简单的异步load()或者require()函数来加载javascript库 如果应用程序不得不执行太多的计算而导致明显的延迟,应该允许文档在执行这个计算之前完全载入,并且确保告诉用户正在进行计算并且浏览

离线应用和web worker

只当自己笔记一样,把自己看的资料整理一下而已,勿喷! 搭建离线应用可以适用于一些小的应用场景.感觉目前用的也不是很多,分为以下几步: ①找到服务器的配置文件,设置头信息 : AddType text/cache-manifest .manifest ② html标签加 : manifest=“xxxxx.manifest”,例如: <html manifest="cache.manifest"> ③写manifest文件 : 离线的清单列表 先写 : CACHE MANIF

深入 HTML5 Web Worker 应用实践:多线程编程

深入 HTML5 Web Worker 应用实践:多线程编程 HTML5 中工作线程(Web Worker)简介 至 2008 年 W3C 制定出第一个 HTML5 草案开始,HTML5 承载了越来越多崭新的特性和功能.它不但强化了 Web 系统或网页的表现性能,而且还增加了对本地数据库等 Web 应用功能的支持.其中,最重要的一个便是对多线程的支持.在 HTML5 中提出了工作线程(Web Worker)的概念,并且规范出 Web Worker 的三大主要特征:能够长时间运行(响应),理想的启

javascript:Web Worker

原文章:https://wangdoc.com/javascript/index.html Web Worker 概述 JavaScript 语言采用的是单线程模型,也就是说,所有任务只能在一个线程上完成,一次只能做一件事.前面的任务没做完,后面的任务只能等着.随着电脑计算能力的增强,尤其是多核 CPU 的出现,单线程带来很大的不便,无法充分发挥计算机的计算能力. Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者

HTML5 Web Worker简单使用

Web Workers 是 HTML5 提供的一个javascript多线程解决方案,我们可以将一些大计算量的代码交由web Worker运行而不冻结用户界面. 一:如何使用Worker Web Worker的基本原理就是在当前javascript的主线程中,使用Worker类加载一个javascript文件来开辟一个新的线程,起到互不阻塞执行的效果,并且提供主线程和新线程之间数据交换的接口:postMessage,onmessage. 那么如何使用呢,我们看一个例子: //worker.jso