Unbuffered (make(chan int)): mỗi lần gửi phải có một bên nhận sẵn sàng ngay tại thời điểm đó — gửi và nhận là một điểm đồng bộ. Buffered (make(chan int, 3)): gửi chỉ chặn khi buffer đầy, nhận chỉ chặn khi buffer rỗng.
go
func main() {
ch := make(chan int)
ch <- 1 // blocks forever: no receiver is ready
fmt.Println(<-ch)
}
// fatal error: all goroutines are asleep - deadlock!Runtime phát hiện mọi goroutine đều đang chặn và không ai còn khả năng đánh thức ai, nên dừng chương trình với fatal error: all goroutines are asleep - deadlock!. Đây là lỗi runtime, recover không bắt được.
Cách sửa: đưa phần nhận sang goroutine khác, hoặc cấp buffer đủ chỗ.
go
ch := make(chan int, 1)
ch <- 1 // fits in the buffer, does not block
fmt.Println(<-ch)Điểm cần nhớ: runtime chỉ báo được khi toàn bộ goroutine ngủ.
Nếu còn một goroutine đang chạy vòng lặp hoặc chờ I/O mạng, chương trình sẽ treo im lặng mà không có thông báo nào.