Bài 2 — Goroutine, Scheduler & GPM Model
Concurrency — Goroutine, Scheduler và GPM Model 1. Problem Statement Bài toán C10K → C10M Một server hiện đại cần phục vụ 10.000 → 10.000.000 kết nối đồng thời. Với mô hình “1 kết nối = 1 OS thread”: Memory: 10.000 thread × 8MB stack (mặc định Linux) = 80GB chỉ cho stack. Bất khả thi. Context switch: chuyển đổi thread qua kernel tốn 1-10µs (lưu/khôi phục register, TLB flush, cache pollution). Với 10K thread active, CPU dành phần lớn thời gian cho việc chuyển đổi thay vì làm việc. Scheduler kernel không biết gì về ngữ nghĩa ứng dụng — nó schedule công bằng theo time-slice, không theo “goroutine này đang chờ I/O”. Các giải pháp cũ và giới hạn Giải pháp Cách hoạt động Giới hạn Thread pool (Java cổ điển) Số thread cố định + queue Thread bị block bởi I/O vẫn chiếm chỗ; sizing pool là nghệ thuật đen Callback / event loop (Node.js, nginx) 1 thread + non-blocking I/O Callback hell; 1 tính toán nặng chặn toàn bộ; code bất đồng bộ “lây nhiễm” (colored functions) Async/await (C#, Rust, JS) Compiler biến đổi thành state machine Vẫn chia thế giới thành sync/async (“function coloring”); ecosystem phải async hết Go chọn hướng thứ ba: viết code tuần tự, blocking như bình thường — runtime lo việc biến blocking thành non-blocking bên dưới. Không có async/await, không có màu hàm. Đây là điểm bán hàng lớn nhất của Go. ...