疑问
在select多路复用中,如何优雅退出goroutine
方法
使用context
package main
import (
"context"
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
func main() {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
ch := make(chan int, 5)
wg.Add(2)
go send(ctx, ch)
go receive(ctx, ch)
time.Sleep(1 * time.Second)
cancel()
wg.Wait()
fmt.Println("stop")
}
func send(ctx context.Context, ch chan int) {
defer wg.Done()
i := 0
for {
select {
case v := <-ctx.Done():
fmt.Println("send Done", v)
return
default:
if i >= 10 {
fmt.Println("send finished")
return
}
ch<-i
fmt.Println("send",i)
}
i++
time.Sleep(200 * time.Millisecond)
}
}
func receive(ctx context.Context, ch chan int) {
defer wg.Done()
for {
select {
case v := <-ctx.Done():
fmt.Println("receive Done", v)
return
case v := <-ch:
fmt.Println("receive", v)
default:
fmt.Println("receive wait")
time.Sleep(1 * time.Second)
}
}
}
结果

可以看到当调用cancel时,会向Done发送一个信号,利用这个信号我们可以退出goroutine
本文介绍了一种在Go语言中优雅地停止协程的方法,通过使用context包来控制多个goroutine的运行和停止,实现多路复用下goroutine的优雅退出。
997

被折叠的 条评论
为什么被折叠?



