使用Go语言的Channel来等待任务完成
发表时间: 2024-04-01 19:58
方法一: 使用Channel来等待goroutine结束
done.go
package mainimport ("fmt")//作为消费者func doWorker(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 doWorker(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 := 0; i < 10; i++ { workers[i].in <- 'a' + i <-workers[i].done } for i := 0; i < 10; i++ { workers[i].in <- 'A' + i <-workers[i].done }}func main() { chanDemo()}
进行改进
done.go
package mainimport ("fmt")//作为消费者func doWork(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 { 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 { worker.in <- 'a' + i } //wait for all of them for _, worker := range workers { <-worker.done } for i, worker := range workers { worker.in <- 'A' + i } //wait for all of them for _, worker := range workers { <-worker.done }}func main() { chanDemo()}
方法二: WaitGroup的使用
sync包提供了基本的同步基元, 如互斥锁。除了Once和WaitGroup类型, 大部分都是适用于低水平程序线程, 高水平的同步使用channel通信更好一些。
done3.go
package mainimport ("fmt""sync")//作为消费者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) for i, worker := range workers { worker.in <- 'a' + i } for i, worker := range workers { worker.in <- 'A' + i } wg.Wait()}func main() { chanDemo()}
改进
package mainimport ("fmt""sync")//作为消费者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) for i, worker := range workers { worker.in <- 'a' + i } for i, worker := range workers { worker.in <- 'A' + i } wg.Wait()}func main() { chanDemo()}