Javascript 的运行及浏览器多线程

原创 2006年12月28日 10:36:00
Javascript 的运行及浏览器多线程

2006.12     lu_yi_ming(_at_)sina.com



_ 本文目的

  网页HTML结构以及 Javascript 程序越来越复杂了,有必要整理一下思路。

  本文只是想整理一下思路,很多细节不一定准确。


_ 问题详述

  现在一个网页中包含了多个 Iframe(Frame),每个 Iframe 都有 window (本文中 window 特指 DOM 中的 window,MS Windows 中的窗口与 X Window 中的窗口用 WINDOW 来表示),每个 window 都可以有 setInterval,以及 setTimeout,另外 window.document 里面还有很多的 element,每个 element 都可以有 event,而且这些 event 可以一直 bubble 到 body。

  问题 1. 在一个 window 内部,event 与 window.setInterval / window.setTimeout 是否并行?
  问题 2. window 之间的 Javascript 是否并行?
  问题 3. 属于同一个进程的 WINDOW 之间的 Javascript 是否并行?
  问题 4. 如果有并行存在,是一种怎么样的并行? 是浏览器为每一个 window 或 WINDOW 模拟了多线程,还是利用操作系统本身的多线程?
  问题 5. 如果有并行存在,如何解决 Javascript 运行中的互斥、信号?


_ 初步认识

  经过一些简单研究(因为懒,没去读 Firefox 源代码),有以下初步认识。

  对于 IE,用 SPY++ 分析,发现增加页面中的 Iframe 并不能导致线程的增加,也不能导致子 WINDOW 的增加。所以,IE 中的 Iframe 及 window 是 Shell.Explorer (shdocvw.dll 中的 COM 组件) 内部实现的,可能在一个单独的线程中,很可能就在 WINDOW 所属的线程中。进一步,WINDOW 中所有 Iframe 的 window 的内部的 Javascript 都是不并行的。再进一步,结合网络传输,如果一个 Iframe.src 赋值后,Javascript 所在的线程应该会通知另一个线程(本文中简称通讯线程)去向服务器发 HTTP 请求。通讯线程从服务器端接收了一个完整的 HTTP 包后,将把这个数据包交给负责显示的线程(中间环节可能有一个线程负责解析 html),显示线程(或解析线程)边显示边运行页面中的 Javascript,例如 document.write()。并不停的绘制屏幕。而在这个 HTTP 数据包处理过程中,并不会处理其他 Iframe 的 window 的 setInterval 之类的事件。处理完一件事情后,才会在内部的 timer / timeout 队列中选择一个到期的开始运行(调用)。

  所以,如果有一个 Iframe 的 window 的 Javascript 陷入死循环,则此线程内的所有的 Iframe 都将停止响应,并且从服务器端接收来的新数据也将被搁置。

  IE 中的多线程。在 IE 上按 Ctrl-N,或者运行 window.open() ,将会打开一个新的 WINDOW,从 SPY++ 中看,会相应的增加一个新线程,管理这个新的 WINDOW。但是没有增加更多的新线程,说明一个进程内所有的 WINDOW 都共用了通讯线程。也就是通讯进程管理了所有的 TCP Connection。 用 window.open() 返回的对象指针可以访问这个新 WINDWO,并且可以访问其下的 Iframe 的 window 中的各种数据,甚至也可以调用其中的函数,只是需要注意堆栈的不同。经过测试,如果两个线程的 Javascript 同时访问同一个数据,比如同时有 window.setInterval 指定的函数去访问一个 window 中的一个 element 的变量,或者修改属性,则其中的一个函数会返回 Javascript Exception:拒绝访问,说明浏览器在内部实现中注意了互斥。

  基于以上认识,对于 IE ,在一个 WINDOW 的所有 Iframe 的 window 内部应该不存在多线程,也不存在 Javascript 并行。当然也不会有 sleep 之类的函数了。把一个 Javascript 函数阻塞了(如特定的 ActiveX )可能导致整个 WINDOW 暂停相应。

  关于 IE 还有一个发现,window.setInterval 不是用 WM_TIMER 实现的。

  关于 Firefox,在 Windows 上,用 SPY++ 分析,页面中的每一个 Iframe 都是用一个 WINDOW 实现的。但是所有的 WINDOW,包括其他 Tab 打开的 WINDOW,都属于一个线程。但是跨 Tab ,跨浏览器窗口访问同时访问一个数据,也会引发 Javascript Exception:拒绝访问,说明 Firefox 的 Javascript 很可能是在一个 Tab 范围内,是不并行的。有可能是 Firefox 给每个 Tab 单独开了一个线程来运行 Javascript。反正最终行为要与 IE 保持差不多,估计也就这样了。

  在 Linux(FC6)上启动 Firefox,用 gdb attach 进去,发现在新打开网页时会增加不少线程,但网页显示稳定后过一段时间,线程数会减少。这也可能是因为运行 Javascript 的线程任务做完了。


_ 初步结论

  1. 在 IE 的一个 WINDOW 内,Firefox 的一个 Tab 内, Javascript 是单线程运行的。
  2. 如果要在页面上的各 Iframe 之间实现 Javascript 同步,则应该采用 window.setInterval 来实现,而不是把一个 Javascript 挂起。
  3. 在 IE 上跨 WINDOW,或在 Firefox 上跨 Tab 访问数据,则要注意用 try catch 解决线程互斥导致的 Exception。

浏览器多线程和js单线程

0.前言开发过程中遇到js线程和ui渲染线程互斥问题。导致ui无法正常更新等问题。这些问题的根源就是因为浏览器的多线程和js的单线程引起的。看本篇博客之前,应该充分理解消息队列,事件循环,同步异步任务...
  • github_34514750
  • github_34514750
  • 2017-08-02 15:13:11
  • 1406

浏览器UI线程 和 js线程

浏览器中的线程介绍       通常一个浏览器会至少存在三个线程:JS引擎线程(用于处理JS)、GUI渲染线程(用于页面渲染)、浏览器时间触发线程(用于控制交互)。      而因为JS可以操作...
  • u011643473
  • u011643473
  • 2015-01-27 10:55:17
  • 3736

Javascript 的运行及浏览器多线程

Javascript 的运行及浏览器多线程2006.12     lu_yi_ming(_at_)sina.com_ 本文目的  网页HTML结构以及 Javascript 程序越来越复杂了,有必要整...
  • putongren
  • putongren
  • 2006-12-28 10:36:00
  • 1797

关于IE的"多线程"...

最近在CSDN社区的AJAX版有些人问道关于AJAX的多线程的问题...在这里我想说下我的看法...IE的线程模式其实是STA(Single-Threaded Apartment)模式... 也就是说...
  • chaircat
  • chaircat
  • 2006-10-03 14:40:00
  • 826

JavaScript引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序

一、浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程。 1. javascript引擎...
  • fivedoumi
  • fivedoumi
  • 2015-07-17 15:58:08
  • 1686

javascript脚本从载入浏览器到显示执行的过程解析

简单的代码: var i = 10; function say(msg){ alert(msg); } ...
  • javaloveiphone
  • javaloveiphone
  • 2015-12-15 00:16:41
  • 762

WebBrowser多线程带来的麻烦

我们在做采集软件的时候 有些网站通过直接分析html文本是很麻烦的事情 在利用WinForm编程的情况下 有一种更好的方式当然是分析HtmlDocument 然而,这HtmlD...
  • gold0523
  • gold0523
  • 2014-06-02 17:41:52
  • 6060

利用IE对多帧GIF的onload事件重复执行的原理实现(JavaScript多线程的实现)

注:以下内容基于IE中GIF的onload事件的基础上,故所有测试IE only需要用到的几个图片:先看一个简单的事实: var img=new Image(); img.src="attachme...
  • canduecho
  • canduecho
  • 2008-05-04 16:13:00
  • 844

JavaScript可以在浏览器地址栏直接执行~

因为最近在学习 JavaScript,发现除了在HTML里嵌入js代码实现特效之外,在浏览器的地址栏里输入js代码也可以得到意想不到的效果,对于不懂js的朋友们照样适用,只要你把这里的js代码粘到你的...
  • xjinza
  • xjinza
  • 2012-12-06 15:40:06
  • 1141

在chrome浏览器中执行javascript

chrome浏览器中包含了开发者工具,chrome浏览器可谓是非常的强大啊,在chrome浏览器上F12就可以打开开发者模式。如下图所示: 下面给大家简单演示一下使用jquery登陆csdn...
  • davidsu33
  • davidsu33
  • 2015-09-25 09:32:18
  • 5839
收藏助手
不良信息举报
您举报文章:Javascript 的运行及浏览器多线程
举报原因:
原因补充:

(最多只允许输入30个字)