Threads
Threads ใน TypeScript vs Rust
หัวข้อที่มีชื่อว่า “Threads ใน TypeScript vs Rust”ใน Node.js หรือ browser คุณรัน JavaScript แบบ parallel บน CPU core อื่นตรง ๆ ไม่ได้ จะ spawn Web Worker ก็ทำได้ แต่ Worker รันอยู่ในกระบวนการแยก: แชร์ closure หรือส่ง reference ข้ามไปไม่ได้ — ส่งได้เฉพาะข้อมูลที่ serialize ได้ผ่าน postMessage เท่านั้น
Rust ให้ OS threads จริง ผ่าน std::thread::spawn threads เหล่านี้รันในกระบวนการเดียวกัน แชร์ address space เดียวกัน และสามารถรับค่า (ไม่ใช่สำเนา) จาก parent thread ได้ — ตราบใดที่ ownership rules ถูกต้อง
std::thread::spawn
หัวข้อที่มีชื่อว่า “std::thread::spawn”thread::spawn รับ closure และรันบน OS thread ใหม่ closure ต้อง move ข้อมูลที่ต้องการจาก scope รอบๆ เพราะ thread อาจมีชีวิตนานกว่า stack frame ปัจจุบัน
การเรียกจะคืนค่า JoinHandle<T> โดยที่ T คือ return type ของ closure การเรียก .join() บน handle จะ block จนกว่า thread จะเสร็จและคืนค่า Result<T, Box<dyn Any>>
// TypeScript (Node.js): ไม่มี real threads// Web Workers รันในกระบวนการแยก// และสื่อสารได้เฉพาะผ่าน postMessage (ข้อมูล serialized)import { Worker, isMainThread, parentPort, workerData } from 'worker_threads';
if (isMainThread) { const worker = new Worker(__filename, { workerData: { value: 10 } }); worker.on('message', (result) => console.log('result:', result));} else { // ใน worker — ไม่สามารถแชร์ closure หรือ reference จาก main thread ได้ parentPort?.postMessage(workerData.value * 2);}use std::thread;
fn main() { let value = 10u32; // owned by main thread
// move closure รับ ownership ของ 'value' let handle = thread::spawn(move || { // 'value' ถูก own โดย thread นี้แล้ว value * 2 });
// join() block จนกว่า thread จะเสร็จ // และคืนค่า return value ของ closure let result = handle.join().unwrap(); println!("result: {result}"); // result: 20}Spawn หลาย thread และรวบรวมผลลัพธ์
หัวข้อที่มีชื่อว่า “Spawn หลาย thread และรวบรวมผลลัพธ์”Pattern ที่พบบ่อยคือ spawn worker threads จำนวนหนึ่ง รวบรวม JoinHandle ทั้งหมดไว้ใน Vec แล้ว join ทั้งหมดและ aggregate ผลลัพธ์
// TypeScript: งาน parallel ผ่าน Promise.allasync function sumChunks(data: number[][]): Promise<number> { const partials = await Promise.all( data.map(chunk => new Promise<number>(resolve => resolve(chunk.reduce((a, b) => a + b, 0)) ) ) ); return partials.reduce((a, b) => a + b, 0);}use std::thread;
fn main() { let chunks: Vec<Vec<u32>> = vec![ vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9], ];
let handles: Vec<_> = chunks .into_iter() .map(|chunk| { thread::spawn(move || chunk.iter().sum::<u32>()) }) .collect();
let total: u32 = handles .into_iter() .map(|h| h.join().unwrap()) .sum();
println!("total: {total}"); // total: 45}ลองรันเลย
หัวข้อที่มีชื่อว่า “ลองรันเลย”use std::thread;
fn main() { let chunks: Vec<Vec<u32>> = vec![ vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9], ];
let handles: Vec<_> = chunks .into_iter() .map(|chunk| { thread::spawn(move || chunk.iter().sum::<u32>()) }) .collect();
let total: u32 = handles .into_iter() .map(|h| h.join().unwrap()) .sum();
println!("total: {total}");}Compiling…