作者TonyQ (自立而後立人。)
看板Ajax
标题Re: [讨论] javascript是共时、多执行绪吗?
时间Fri Nov 4 22:43:06 2011
※ 引述《ec75413 (无亏/明月几时有?)》之铭言:
: 在这里没找到类似的讨论串 网路上中文的也很少
: 但英文还算不少
: 所以把这个议题放上来。
: 不知这个问题已经是老梗了 还是...?
javascript 是同步的
也就是不会有两行 statement 同时执行的
但是他可以是多执行续。
也就是假设你有一个 funciont 是
function A(){
alert("A");
alert("B");
}
function B(){
alert("C");
alert("D");
}
透过 setTimeout / setItnerval ,
是有可能会发生这样的执行序
alert("A");//from A
alert("C");//from B
alert("B");//from A
alert("D");//from B
你把 js 底层的引擎想像成一个 queue ,
有要执行的指令就推进去,引擎会去跑他,
但同时间他只能处理一个指令。
一般当你真的很需要控制执行的顺序的时候,
我们会多加几个 flag 作为 lock ,或者自己实做queue。
但是基本上 javascript 要作到 java 的 synchronized keyword 做的事情,
是没有办法保证一定做的到的,最好尽量避免这麽严苛的状况。:P
--
网页上拉近距离的帮手 实现 GMail丰富应用的功臣
数也数不清的友善使用者体验 这就是javascript
欢迎同好到 AJAX 板一同讨论。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 198.203.175.175
※ 编辑: TonyQ 来自: 198.203.175.175 (11/04 22:45)
1F:→ tyf99:我觉得 js 的能耐,还是要看 browser 的 js 引擎 11/05 00:25
2F:→ tyf99:browser js vm 够好,js 可做到的事超乎想像 11/05 00:26
3F:→ sk1765:我实测的结果 AB一定一起出现 CD一定一起出现 不会AC BD 11/05 01:16
4F:→ sk1765:我的程式是 12一组 34一组 不会13 24 只会 1234或3412 11/05 01:18
6F:→ sk1765:所以两个function内部的每一行statement也是不分的 11/05 01:20
7F:→ sk1765:只要包成一个function 两function都是顺序执行 11/05 01:21
8F:→ sk1765:没有打散一行一行 一起同步 所以应该完全没有synchronized 11/05 01:23
9F:→ sk1765:的要求 因为实测看来他都是整个function丢到queue里排队 11/05 01:24
10F:推 linhomeyeu:看浏览器实作吧 这部分语言本身没有规范 11/05 01:25
11F:→ linhomeyeu:也就是可以同步。 玩玩看Node.JS吧这边好像没人在玩? 11/05 01:25
12F:→ sk1765:Node.JS不知道server哪里有可以下载 所以一直没玩 11/05 01:33
13F:推 LaPass:那请问,如果A、B间插一个Thread.Sleep(30000);之类的东西 11/05 01:34
14F:→ LaPass:会怎麽办?或是无限回圈、或是会执行很久的程式码。 11/05 01:35
15F:→ LaPass:我只看过js的使用手册而已,还不太会.... 11/05 01:36
16F:→ sk1765:所以javascript才会根本没有sleep这种东西 11/05 01:38
17F:→ sk1765:因为根本没有thread 不能多工 这是我的认知 11/05 01:39
18F:推 LaPass:原来如此,了解.... 11/05 02:27
19F:→ tyf99:google 了一下,js 多工与否完全系於 browser vm 上 11/05 02:31
20F:→ tyf99:但是以往的 js 程式,几乎全以没有多工的考量下去写的 11/05 02:31
21F:→ tyf99:google chrome 好像曾经有把多工给加上去 11/05 02:32
22F:→ tyf99:结果在许多现有的网页下,会出现 concurrency issues 11/05 02:33
23F:→ tyf99:所以可以说 "目前通用的 browser vm,都不让 js 多工" 11/05 02:34
24F:→ TonyQ:ACBD是可能会出现的,但是会出现在复杂的测试环境下。 11/05 04:30
25F:→ TonyQ:当你页面中有多个script file 同时读取时,这偶尔会发生。 11/05 04:30
26F:→ TonyQ:其实复杂的状况是在於像是你塞多个script tag到head 11/05 04:31
27F:→ TonyQ:然後同时你又进行script的读取,同时间你又有setTimeout 11/05 04:31
28F:→ TonyQ:setInterval , 有些状况下你很难确保当时的变数状况. 11/05 04:31
29F:→ TonyQ:synchronized 的要求一定存在,因为你可能透过 closure 存取 11/05 04:32
30F:→ TonyQ:外面的变数,此时你如何确保 setTimeout 跟外面的执行续。:P 11/05 04:33
31F:→ TonyQ:另外 js 基本上不作成multiple thread 不是因为没有考量, 11/05 04:34
32F:→ TonyQ:是因为在 multiple thread的状况下要维持变数状态变得很困难 11/05 04:34
33F:→ TonyQ:像是java要在thread里面存取的变数也必须设成final一样 11/05 04:37
34F:→ TonyQ:但是js 没有这类的限制 所以设计起来会很困难... 11/05 04:37
35F:→ TonyQ:做不到这件事情不是说他差,做得到也不见得就是好事,只是 11/05 04:40
36F:→ TonyQ:陈述一种语言特性而已。事实上我处理的复杂状况是在几万行js 11/05 04:40
37F:→ TonyQ:的同时执行下才出现的复杂条件,一般状况下也很难碰到。XD 11/05 04:41
38F:→ TonyQ:我是觉得应该要尽量避免这麽严苛的情况,:P 11/05 04:42
39F:→ TonyQ:举例按着按键不放时,只要设立一个「处理中」的flag, 11/05 04:42
40F:→ TonyQ:当处理中就忽略之後送来的相同事件之类的。 11/05 04:42
41F:→ TonyQ:这种处理方案在各种 widget 中很常见。 11/05 04:43
42F:推 ec75413:所以说 Bakery Algorithm 依然是「割鸡用牛刀」罗? 11/05 09:52
43F:→ sk1765:你们可能想得太复杂了 反正他就是一个queue 任何执行段都 11/05 10:14
44F:→ sk1765:丢到这个queue排队 决不会有两个执行段同时间交错执行 11/05 10:15
45F:→ sk1765:至少在browser client端是这样 至於node.js要变成server端 11/05 10:17
46F:→ sk1765:他很有可能会做multithread 不然就不叫server了吧 11/05 10:18
47F:→ sk1765:我是不知道asp jsp php是不是也可以thread 但java可以 11/05 10:18
48F:→ sk1765:另外<script>tag他也是一整个tag视成一个执行段 觉不会有 11/05 10:20
49F:→ sk1765:两个<script>同时交错执行 但是有载入先後的问题 11/05 10:20
50F:→ sk1765:那只要简单的flag判断必须先载入的是否完成就行了 11/05 10:21
51F:→ sk1765:当然如果把程式分在很多<script>里 这样不断的放入<script> 11/05 10:22
52F:→ sk1765:这样就有可能造成程式是一小段一小段的交错 11/05 10:23
53F:→ sk1765:可是这不是synchronized的问题阿 synchronized只在确保他的 11/05 10:28
54F:→ sk1765:段落里是互斥的critical section 11/05 10:30
55F:→ sk1765:在queue里基本上就已经是一个critical section了因为他排队 11/05 10:34
56F:→ sk1765:执行 如果不这样 我们光是作<script src='a.js'> 11/05 10:36
57F:→ sk1765:<script src='b.js'> 两个script交错执行的话 程式恐怕不是 11/05 10:37
58F:→ sk1765:我们平常这样一行一行写 但这种挂很多js平常就很常见阿 11/05 10:38
59F:→ sk1765:程式里也不用做synchronized 顶多就判断是否载入完成 11/05 10:39
60F:→ sk1765:总之 在同一个<script>里 是没有synchronized的问题的 11/05 10:43
61F:→ legnaleurc:照你的说法,单核的OS也没有multithread,反正都是丢到 11/05 15:34
62F:→ legnaleurc:task queue 里执行不是吗? 11/05 15:35
63F:推 UniFish:nodeJS举手 11/05 21:00
64F:→ TonyQ:最好是一个script 是一个执行段,那script里面的setTimeout 11/05 22:42
65F:→ TonyQ:要怎麽算在同一个执行段?下一个<script>必须等到上一个的 11/05 22:42
66F:→ TonyQ:setTimeout或setInterval都跑完才能动? 11/05 22:43
67F:→ TonyQ:还是你说script 里面的timeout 是另外当成独立的执行段? 11/05 22:44
68F:→ TonyQ:基本上真正的 critical session 碰见的机率并不高,因为一般 11/06 11:33
69F:→ TonyQ:而言 script 的执行表现都不错,只有在很极端的状况会碰到。 11/06 11:33
70F:→ TonyQ:我也只有碰过2-3次而已,所基本上可以当特例看。 11/06 11:34
71F:→ tyx:多工不一定是 multithread 11/07 03:49
72F:→ tyx:Non - Preemptive Multitasking 就不是 11/07 03:55
73F:→ tyx:也没有 synchronize 问题 11/07 03:57
74F:→ sk1765:恩 我的用词不精准 跟多工没关系 11/07 14:08