buffered_channels_close.go 863 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. "time"
  6. )
  7. const (
  8. jobCount = 10
  9. workerCount = 3
  10. bufferSize = 5 // 缓冲通道
  11. )
  12. func main() {
  13. jobs := make(chan int, bufferSize)
  14. var wg sync.WaitGroup
  15. // 1. 启动 worker(fan-out)
  16. for w := 1; w <= workerCount; w++ {
  17. wg.Add(1)
  18. go worker(w, jobs, &wg)
  19. }
  20. // 2. 发送任务(主 goroutine)
  21. for j := 1; j <= jobCount; j++ {
  22. jobs <- j
  23. }
  24. close(jobs) // 关键:关闭通道,让 range 自然结束
  25. // 3. 等待所有 worker 处理完
  26. wg.Wait()
  27. fmt.Println("all jobs done")
  28. }
  29. func worker(id int, jobs <-chan int, wg *sync.WaitGroup) {
  30. defer wg.Done()
  31. // range 会在通道关闭且读完剩余数据后自动退出
  32. for j := range jobs {
  33. fmt.Printf("worker-%d processing job-%d\n", id, j)
  34. time.Sleep(300 * time.Millisecond) // 模拟耗时
  35. }
  36. fmt.Printf("worker-%d shutdown\n", id)
  37. }