示例1:接收者主动通知发送者已经完成任务
func doWork(id int, c chan int, done chan bool) {
for n := range c {
fmt.Printf("Worker %d received %c\n", id, n)
done <- true
}
}
type worker struct {
in chan int
done chan bool
}
func createWorker(id int) worker {
w := worker{
in: make(chan int),
done: make(chan bool),
}
go doWork(id, w.in, 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 {
workers.in <- 'a' + i
}
for _, worker := range workers {
<-worker.done
}
for i, worker := range workers {
workers.in <- 'A' + i
}
for _, worker := range workers {
<-worker.done
}
}
func main() {
chanDemo()
}
示例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()
}