Go语言中的go-routine是go语言中的最重要的一部分,是一个用户级的线程是Go语言实现高并发高性能的重要原因.但是如何停止一个已经开启的go-routine呢?一般有几种方法:
- 使用共享内存来停止go-routine,比如通过判断一个全局变量来判断是否要停止go-routine
- 使用文件系统来停止go-routine,跟使用内存相同用文件来判断
- 使用context上下文,context也是大家最推荐的一种方式.并且可以结束嵌套的go-routine.
简单使用
context库中,有4个关键方法:
WithCancel
返回一个cancel函数,调用这个函数则可以主动停止go-routine.WithValue
WithValue可以设置一个key/value的键值对,可以在下游任何一个嵌套的context中通过key获取value.但是不建议使用这种来做go-routine之间的通信.WithTimeout
函数可以设置一个time.Duration,到了这个时间则会cancel这个context.WithDeadline
WithDeadline函数跟WithTimeout很相近,只是WithDeadline设置的是一个时间点.
package mainimport ("context""fmt""time"
)func main() {//cancelctx, cancel := context.WithCancel(context.Background())go work(ctx, "work1")time.Sleep(time.Second * 3)cancel()time.Sleep(time.Second * 1)// with valuectx1, valueCancel := context.WithCancel(context.Background())valueCtx := context.WithValue(ctx1, "key", "test value context")go workWithValue(valueCtx, "value work", "key")time.Sleep(time.Second * 3)valueCancel()// timeoutctx2, timeCancel := context.WithTimeout(context.Background(), time.Second*3)go work(ctx2, "time cancel")time.Sleep(time.Second * 5)timeCancel()// deadlinectx3, deadlineCancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second*3))go work(ctx3, "deadline cancel")time.Sleep(time.Second * 5)deadlineCancel()time.Sleep(time.Second * 3)}func workWithValue(ctx context.Context, name string, key string) {for {select {case <-ctx.Done():fmt.Println(ctx.Value(key))println(name, " get message to quit")returndefault:println(name,