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。

关于大量iframe加载的解决方案

手头的一个项目,根据客户的要求,在前端自动生成大量的iframe,比如90个iframe,而且这些iframe是嵌套在一个大的iframe下的,不要问我为什么这样。方案1:将动态生成的url,附加到i...
  • zdavb
  • zdavb
  • 2015年11月13日 14:52
  • 7541

深入理解iframe

http://www.cnblogs.com/fangjins/archive/2012/08/19/2645631.html 一 目的   iframe是网页布局中重要的元素,是解决...
  • liumf2005
  • liumf2005
  • 2014年07月05日 00:08
  • 1559

使用ThreadLocal解决多线程的并发问题

早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。 ...
  • z69183787
  • z69183787
  • 2014年08月07日 18:03
  • 1916

浏览器多线程和js单线程

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

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

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

多线程实例详解

多线程的概念在此就不多说了,打个通熟易懂比方,把自己看做一个进程,做的每件事都看做为线程,自己可以同时玩魔兽和听歌,那么玩魔兽和听歌就是两个线程,为多线程。     java是少数集中支持多线程的语...
  • tjcyjd
  • tjcyjd
  • 2012年06月26日 23:21
  • 4419

AB Commander XP V6.6

 AB Commander XP V6.6 软件大小: 668 KB 软件语言: 简体中文 软件类别: 汉化补丁 / 共享软件 /...
  • PCInformation
  • PCInformation
  • 2008年03月13日 12:48
  • 78

在chrome浏览器中执行javascript

chrome浏览器中包含了开发者工具,chrome浏览器可谓是非常的强大啊,在chrome浏览器上F12就可以打开开发者模式。如下图所示: 下面给大家简单演示一下使用jquery登陆csdn...
  • davidsu33
  • davidsu33
  • 2015年09月25日 09:32
  • 4906

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

简单的代码: var i = 10; function say(msg){ alert(msg); } ...
  • javaloveiphone
  • javaloveiphone
  • 2015年12月15日 00:16
  • 642

IFrame的用法

IFrame介绍: 也应该是框架的一种形式,iframe和frame比较相似,但是有一个根本的区别,iframe可以活动,而frame是不可活动的。换句话说,iframe可以指定其坐标位置。 大部...
  • hejingyuan6
  • hejingyuan6
  • 2013年11月27日 21:24
  • 7011
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Javascript 的运行及浏览器多线程
举报原因:
原因补充:

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