🔴 Process
Chương trình đang chạy. Bộ nhớ riêng biệt, cách ly hoàn toàn. Crash 1 process ≠ ảnh hưởng process khác.
🔵 Thread
Đơn vị thực thi nhỏ nhất trong process. Chia sẻ bộ nhớ với threads khác cùng process.
1. Process
Process A (PID 1234) Process B (PID 5678)
┌──────────────────┐ ┌──────────────────┐
│ Code segment │ │ Code segment │
│ Data segment │ │ Data segment │
│ Heap │ │ Heap │
│ Stack │ │ Stack │
│ File handles │ │ File handles │
└──────────────────┘ └──────────────────┘
Bộ nhớ RIÊNG Bộ nhớ RIÊNG
↑ CÁCH LY ↑ ↑ CÁCH LY ↑
→ 2 processes KHÔNG chia sẻ bộ nhớ
→ Giao tiếp qua IPC (pipe, socket, shared memory)
// Node.js: Multi-process (cluster module)
const cluster = require('cluster');
const os = require('os');
if (cluster.isPrimary) {
// Master process tạo workers
const numCPUs = os.cpus().length;
for (let i = 0; i < numCPUs; i++) {
cluster.fork(); // Tạo child PROCESS (bộ nhớ riêng)
}
cluster.on('exit', (worker) => {
console.log(`Worker ${worker.process.pid} died`);
cluster.fork(); // Restart worker
});
} else {
// Worker process (mỗi worker = 1 process riêng)
const express = require('express');
const app = express();
app.listen(3000);
}
2. Thread
Process (PID 1234)
┌──────────────────────────────────┐
│ Code segment (SHARED) │
│ Data segment (SHARED) │
│ Heap (SHARED) │
│ │
│ ┌─────────┐ ┌─────────┐ │
│ │ Thread 1│ │ Thread 2│ │
│ │ Stack 1 │ │ Stack 2 │ │
│ │ Reg. 1 │ │ Reg. 2 │ │
│ └─────────┘ └─────────┘ │
│ │
│ → Threads CHIA SẺ heap, code │
│ → Mỗi thread có stack RIÊNG │
└──────────────────────────────────┘
// Node.js: Worker Threads (chia sẻ bộ nhớ)
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
if (isMainThread) {
// Main thread
const sharedBuffer = new SharedArrayBuffer(4); // Shared memory!
const worker = new Worker(__filename, {
workerData: { sharedBuffer }
});
worker.on('message', (msg) => console.log('Result:', msg));
} else {
// Worker thread (chia sẻ memory với main thread)
const { sharedBuffer } = workerData;
const arr = new Int32Array(sharedBuffer);
arr[0] = 42; // Ghi trực tiếp vào shared memory
parentPort.postMessage('Done!');
}
3. Bảng So Sánh
| Tiêu chí | 🔴 Process | 🔵 Thread |
|---|---|---|
| Bộ nhớ | Riêng biệt, cách ly | Chia sẻ heap, code |
| Tạo/hủy | Tốn kém (heavy) | Nhẹ (lightweight) |
| Context switch | Chậm (đổi toàn bộ) | Nhanh (chỉ đổi stack, registers) |
| Giao tiếp | IPC (pipe, socket, SharedMem) | Shared memory (trực tiếp) |
| Crash | Không ảnh hưởng process khác | Crash thread → crash cả process |
| Race condition | Ít (bộ nhớ riêng) | Dễ xảy ra (shared memory) |
| Ví dụ | Chrome tabs, Node cluster | Java threads, Go goroutines |
4. Race Condition — Vấn Đề Của Threads
⚠️ Race Condition: Khi 2+ threads cùng đọc/ghi shared data → kết quả không đoán
trước.
Thread A: read count (0) → +1 → write (1)
Thread B: read count (0) → +1 → write (1)
Kết quả: count = 1 (đáng lẽ phải = 2!) 💀
Giải pháp: Mutex, Semaphore, Atomic operations, Lock-free data structures.
5. Khi Nào Dùng?
Multi-process khi: Cần isolation (security), fault tolerance, khác ngôn
ngữ/runtime.
Multi-thread khi: Cần shared memory, performance, lightweight
parallelism.
Node.js: cluster (multi-process) cho web server, worker_threads (multi-thread)
cho CPU-bound.