11.2 使用Channel等待任务结束

一、等待任务

  1. 手动编写等待任务

    package main
    
    import (
    	"fmt"
    )
    
    func doWorker(id int, c chan int, done chan bool) {
    	for n := range c {
    		fmt.Printf("Worker %d received %c \n", id, n)
    		// 通知外部打印完成,防止外部循环等待(大小写一起等待反馈)
    		go func() {
    			done <- true   // 如果下面每组输入输出结束后直接接收,则只有这句即可
    		}()
    	}
    }
    
    type worker struct {
    	id   chan int
    	done chan bool
    }
    
    func createWorker(i int) worker {
    	w := worker{
    		id:   make(chan int),
    		done: make(chan bool),
    	}
    	go doWorker(i, w.id, w.done)
    	return w
    }
    
    func chanDemo() {
    	var workers [10]worker
    	for i := 0; i < 10; i++ {
    		workers[i] = createWorker(i)
    	}
    	for i, worker := range workers {
    		worker.id <- 'a' + i
    	}
    	for i, worker := range workers {
    		worker.id <- 'A' + i
    	}
    
    	// 大小写一起等待输出
    	for _, worker := range workers {
    		<-worker.done
    		<-worker.done
    	}
    }
    
    func main() {
    	chanDemo()
    }
  2. 使用go的WaitGroup进行等待

    package main
    
    import (
    	"fmt"
    	"sync"
    )
    
    func doWorker(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 {
    	id chan int
    	wg *sync.WaitGroup
    }
    
    func createWorker(i int, wg *sync.WaitGroup) worker {
    	w := worker{
    		id: make(chan int),
    		wg: wg,
    	}
    	go doWorker(i, w.id, wg)
    	return w
    }
    
    func chanDemo() {
    
        // 使用sync.WaitGroup进行等待
    	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 {
    		worker.id <- 'a' + i
    	}
    
    	for i, worker := range workers {
    		worker.id <- 'A' + i
    	}
    
    	wg.Wait() // 等待任务昨晚
    
    }
    
    func main() {
    	chanDemo()
    }

Last updated

Was this helpful?