使用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()}