作者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