ข้ามไปยังเนื้อหา

ภาพรวม Concurrency

JavaScript ทำงานบน single thread เพียง thread เดียว Event loop ประมวลผลทีละ task แล้วมอบงาน I/O ให้ระบบปฏิบัติการจัดการต่อ

Concurrency ใน JS เป็นแบบ cooperative: โค้ดของคุณยอมคืน control เมื่อถึง await แล้ว event loop จึงหยิบ callback ตัวถัดไปมาทำงาน ผลคือไม่มีอะไรรันแบบ parallel จริง ๆ ภายใน JS process เดียว ยกเว้นจะเปิด Web Worker ที่เป็นกระบวนการแยกที่คุยกันผ่าน postMessage เท่านั้น

Rust ใช้แนวทางที่ต่างออกไปสิ้นเชิง คุณได้ OS thread จริง ตั้งแต่ต้น ได้ระบบ async/await ที่รันบน user-space runtime (Tokio คือตัวเลือกมาตรฐาน) และได้ compiler ที่ กัน data race แบบ static ตั้งแต่ compile time ทาง Rust เรียกสิ่งนี้ว่า fearless concurrency — คุณเขียนโค้ด concurrent ได้เต็มที่ แล้ว compiler จะปฏิเสธการ compile โปรแกรมที่มี data-race bug

โมเดลPrimitive ใน Rustคู่เทียบใน JS
OS threads (ทำงานแบบ parallel บน CPU)std::thread::spawnWeb Workers (จำกัด)
Async I/O (tasks จำนวนมาก, thread pool เดียว)async/await + TokioPromise / async/await
Shared mutable state (ข้าม threads)Arc<Mutex<T>>SharedArrayBuffer + Atomics
Message passing (ข้าม threads)std::sync::mpscworker.postMessage

ระบบ ownership และ type ของ Rust บังคับกฎสองข้อ ณ compile time:

  • ค่าหนึ่งค่าสามารถมี ผู้อ่านหลายคน หรือ ผู้เขียนหนึ่งคน — ไม่ใช่ทั้งคู่พร้อมกัน
  • ข้อมูลที่แชร์ข้าม threads ต้อง implement marker traits Send และ Sync ซึ่ง compiler ตรวจสอบให้อัตโนมัติ

ถ้าคุณพยายามแชร์ &mut T ดิบๆ ข้าม threads โปรแกรม จะ compile ไม่ผ่าน ไม่มี runtime lock ไม่มีการ corrupt แบบเงียบๆ — bug ถูกจับก่อนโค้ดจะรัน

TypeScript
// JavaScript: single-threaded, concurrency via event loop
async function fetchAll(urls: string[]): Promise<string[]> {
// All fetches start "in parallel" (concurrent I/O)
// but JS code itself runs on one thread
return Promise.all(urls.map(url => fetch(url).then(r => r.text())));
}
// Web Worker for CPU-bound parallelism (separate process)
const worker = new Worker('./worker.js');
worker.postMessage({ data: [1, 2, 3] });
worker.onmessage = (e) => console.log(e.data);
Rust
use std::thread;
fn main() {
// Real OS thread — runs truly in parallel on another CPU core
let h1 = thread::spawn(|| "fearless");
let h2 = thread::spawn(|| "concurrency");
// join() waits for the thread and returns its result
let r1 = h1.join().unwrap();
let r2 = h2.join().unwrap();
println!("{r1} {r2}"); // fearless concurrency
}
use std::thread;
fn main() {
let h1 = thread::spawn(|| "fearless");
let h2 = thread::spawn(|| "concurrency");
let r1 = h1.join().unwrap();
let r2 = h2.join().unwrap();
println!("{r1} {r2}");
}
JavaScript บรรลุ concurrency ได้อย่างไร?
'Fearless concurrency' ของ Rust หมายความว่าอะไร?
Rust primitive ตัวไหนที่คล้ายกับ JS's async/await + Promise.all มากที่สุด?