01 JavaScript is more than single-threaded
01 JavaScript is more than single-threaded

01 JavaScript is more than single-threaded

Description
平常沒什麼機會特別寫多執行緒的程式,而 Thread 的創建成本相對低廉,如果我們在適合平行執行的任務中使用多個 thread,並且硬體也支援的話,那會對於效能的提升產生顯著的影響力!
Created
Jan 17, 2024 07:52 AM
Tags
JS Multithreaded
Note
 
 
最近在讀 JavaScript Multithreaded 這本書,希望可以做個書摘連載

全書終極目標

  • JavaScript Multithreading programming
  • Understanding of web worker API , pros and cons, and when to use
    • message passing
    • shared memory

Prerequisite: Cost,為什麼 Thread 比較便宜?

  • Creation Cost && Context Switch Cost:
    • 相較 process,Thread 需要創建的項目少
    • Context Switch 需要暫存的東西也少
    • 甚至不用做 Interprocess-communication (IPC)
    • 題外話:Event loop 帶來的好處是直接避免掉 Context Switch
    • notion image
  • Share
    • Code
    • Shared Memory (heap) (static/global variables)
    • OS resources (e.g. open files and signals)
  • Not share
    • PC program counter -> thread 各自 instruction 執行到的位置
    • register set -> context switch 的時候暫存 instruction 用到的資料
    • stack
    • TLS (Thread Local Storage)
    • thread ID
  • 一些有趣的延伸主題
    • 既然 Thread 共享記憶體,要怎麼避免 Race Condition?
    • Goroutine 是什麼、為什麼要用、有什麼優缺點、應用在哪
    • Coroutine 是什麼、為什麼要用、有什麼優缺點、應用在哪

Concurrency vs Parallel

notion image

Multithreaded、Parallel 一定永遠比較好嗎?

  • 取決於硬體,假設 CPU core 比 user thread 少的話,會有 context switch 的成本
  • 除此之外也要考量到 synchronization 的成本
    • 1. 鎖(Locks)的使用和競爭
      • 例子:假設有一個共享的資料結構,如一個列表,多個線程需要對其進行讀寫操作。為了避免資料競爭(data race),我們通常會使用鎖來同步對共享資料的訪問。
      • 成本:當多個線程嘗試同時獲取鎖時,只有一個線程可以持有鎖,其他線程則被阻塞,直到鎖被釋放。這個等待過程會造成性能的顯著下降,尤其是在鎖競爭激烈的情況下。
    • 2. 死鎖(Deadlock)
      • 例子:兩個或多個線程相互等待對方釋放資源,從而陷入永久的等待狀態。例如,線程 A 持有資源 1 並等待資源 2,同時線程 B 持有資源 2 並等待資源 1。
      • 成本:死鎖導致系統效能完全喪失,因為涉及的線程都不能繼續執行。解決死鎖通常需要複雜的策略和額外的編程工作。
  • 還要考慮到問題的可分割性。並行和多線程特別適合於可以被分割成獨立或半獨立子任務的問題
  • 程式碼複雜度也須考慮進來

JavaScript 到底是 single-threaded 還是 multi-threaded ?

  • JavaScript 原生沒有 thread 相關模組可以呼叫 --> 不能呼叫出第二條 thread
    • JavaScript 是基於單線程模型的語言
    • JavaScript 在其主要的 runtime 中運行在單一的 thread 中。所以 JavaScript 程序一次只能執行一個任務。這種設計可以簡化 event oriented programming,減少與多線程相關的複雜性,如 race condition / synchronization 問題
  • Web Workers 提供了類似 multi-threaded 的功能
    • Web Workers 是瀏覽器實現的,不是 JavaScript 原生的東西。雖然 JavaScript 的 main thread 是 single-threaded 的,但現代的瀏覽器環境提供了 Web Workers API,使得在背景線程中執行JavaScript代碼成為可能。
    • 這些 Web Workers 運行在與主執行線程分離的自己的全局上下文中,允許執行耗時任務而不阻塞 UI。
  • 類似於 Thread 但有差異
    • Web Workers 運行在自己的 context,無法直接訪問 DOM 或其他一些瀏覽器特定的 API。
    • 它們與主線程之間的通信基於 message-passing,意味著數據是通過 copy 而不是 share 來傳遞。
  • 使用場景
    • Web Workers 適用於那些需要長時間計算而不希望影響用戶界面響應性的任務。例如,處理大量數據、執行複雜算法或加載大型資源等。

Realm?為什麼會提到他?

  • a realm as basically an ecosystem in which a JavaScript program lives, it provides different elements that JavaScript programs must have in order to exist within it.
  • Realm 的中文叫做「領域」,提供了以下三樣元素,讓 JavaScript 可以活在裡面
    • global executing environment:類似 window / web worker / frame / node.js 各自程式執行的 scope 都不會互相影響彼此
    • global object:不同的 "領域" 底下會有各自隸屬於彼此的 global object,互不干涉
      • 可以用 instanceof 檢查看看,把在領域A創建的 Array aaa 拿去領域B檢查,會因為創建的 constructor 所在的領域不一樣,導致 isinstanceof 檢查結果為否
    • JavaScript 本人:像是居民的概念
  • 但如果今天希望跨 realm 交流,可以透過像是 message-passing 的方式傳遞 object
    • window.postMessage -> 但原理不是 call by value 或 call by reference,這個需要委託大家好奇的話查一下,搞不好後面章節會提到也不一定

實作:1 thread vs 4 threads

  • 我們可以說程式執行時間縮短四倍嗎?
    • 不行!考量進 thread 初始化成本、列印在 terminal 的 IO 時間,就不會是完整的四倍速
    • Multithread 應用場景:適合可拆分平行工作的任務
    • Multithread 缺點:需要處理 synchronization 問題

小結:可以多認識一下 Thread

平常沒什麼機會特別寫多執行緒的程式,而 Thread 的創建成本相對低廉,如果我們在適合平行執行的任務中使用多個 thread,並且硬體也支援的話,那會對於效能的提升產生顯著的影響力!