示例1:接收者主动通知发送者已经完成任务

    1. func doWork(id int, c chan int, done chan bool) {
    2. for n := range c {
    3. fmt.Printf("Worker %d received %c\n", id, n)
    4. done <- true
    5. }
    6. }
    7. type worker struct {
    8. in chan int
    9. done chan bool
    10. }
    11. func createWorker(id int) worker {
    12. w := worker{
    13. in: make(chan int),
    14. done: make(chan bool),
    15. }
    16. go doWork(id, w.in, w.done)
    17. return w
    18. }
    19. func chanDemo() {
    20. var workers [10]worker
    21. for i := 0; i < 10; i++ {
    22. workers[i] = createWorker(i)
    23. }
    24. for i, worker := range workers {
    25. workers.in <- 'a' + i
    26. }
    27. for _, worker := range workers {
    28. <-worker.done
    29. }
    30. for i, worker := range workers {
    31. workers.in <- 'A' + i
    32. }
    33. for _, worker := range workers {
    34. <-worker.done
    35. }
    36. }
    37. func main() {
    38. chanDemo()
    39. }

    示例2:使用waitGroup来等待多个任务完成

    func doWork(id int, c chan int, wg *sync.WaitGroup) {
        for n := range c {
            fmt.Printf("Worker %d received %c\n", id, n)
            wg.Done() // 任务完成
        }
    }
    
    type worker struct {
        in chan int
        wg *sync.WaitGroup
    }
    
    func createWorker(id int, wg *sync.WaitGroup) worker {
        w := worker{
            in: make(chan int),
            wg: wg,
        }
        go doWork(id, w.in, wg)
        return w
    }
    
    func chanDemo() {
        var wg sync.WaitGroup
    
        var workers [10]worker
        for i := 0; i < 10; i++ {
            workers[i] = createWorker(i, &wg)
        }
    
        wg.Add(20) // 添加20个任务
        for i, worker := range workers {
            workers.in <- 'a' + i
        }
    
        for i, worker := range workers {
            workers.in <- 'A' + i
        }
    
        wg.Wait() // 等待任务完成
    }
    
    func main() {
        chanDemo()
    }
    

    将上述代码进行包装(重构):

    func doWork(id int, w worker) {
        for n := range w.in {
            fmt.Printf("Worker %d received %c\n", id, n)
            w.done()
        }
    }
    
    type worker struct {
        in chan int
        done func()
    }
    
    func createWorker(id int, wg *sync.WaitGroup) worker {
        w := worker{
            in: make(chan int),
            done: func() {
                wg.Done() // 任务完成
            },
        }
        go doWork(id, w)
        return w
    }
    
    func chanDemo() {
        var wg sync.WaitGroup
    
        var workers [10]worker
        for i := 0; i < 10; i++ {
            workers[i] = createWorker(i, &wg)
        }
    
        wg.Add(20) // 添加20个任务
        for i, worker := range workers {
            workers.in <- 'a' + i
        }
    
        for i, worker := range workers {
            workers.in <- 'A' + i
        }
    
        wg.Wait() // 等待任务完成
    }
    
    func main() {
        chanDemo()
    }