如何优雅地退出goroutine

一.在Go语言中有两种较为优雅的方式退出goroutine

1.使用自定义channel通知goroutine退出。
2.使用context传递上下文通知goroutine退出。(官方推荐;本质上也是通过channel通知)

自定义channel版本:

package main
import (
    "fmt"
    "time"
)
//如何优雅地退出goroutine
//1.使用自定义channel版本
func worker(exit_ch chan struct{}){
   for{
      fmt.Println("worker")
      time.Sleep(time.Second*1)
      select{
         case <-exit_ch:
         return
         default:
      }
   }
}
func main() {
   exit_ch := make(chan struct{})
   go worker(exit_ch)
   time.Sleep(time.Second*5)
   exit_ch<-struct{}{}
   close(exit_ch)
   fmt.Println("over")
}

官方版本:
官方推荐版本,明显是优于自定义channel版本,因为官方context里面已经统一为我们定义了channel;更重要的是,使用context我们可以取消多个goroutine,下面代码中我们在worker中新开了一个worker2的goruntine,调用cancel也会通知worker2退出。

package main
import "fmt"
import "time"
import "context"

func worker(ctx context.Context) {
   go worker2(ctx)//在子go中再开一个go,传入ctx
LOOP:
    for {
        fmt.Println("worker")
        time.Sleep(time.Second)
        select {
        case <-ctx.Done(): // 等待上级通知
            break LOOP
        default:
        }
    }
}
//主线程调用cancle(),worker2也能收到通知退出。
func worker2(ctx context.Context){
   LOOP:
    for {
        fmt.Println("worker2")
        time.Sleep(time.Second)
        select {
        case <-ctx.Done(): // 等待cancel通知
            break LOOP//跳出外层循环
        default:
        }
    }
}
func main() {
      ctx,cancel := context.WithCancel(context.Background())   
      go worker(ctx)
      time.Sleep(time.Second*5)
      //通知子goroutine
      cancel()
      fmt.Println("cancel")
      time.Sleep(time.Second*5)
      fmt.Println("over")
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 在工程化的Go语言开发项目中,Go语言的源码复用是建立在包(package)基础之上的。本文介绍了Go语言中如何定...
    雪上霜阅读 1,814评论 0 0
  • 并发(并行),一直以来都是一个编程语言里的核心主题之一,也是被开发者关注最多的话题;Go语言作为一个出道以来就自带...
    驻马听雪阅读 8,286评论 3 27
  • chap8 高性能异步编程框架和中间件 NettyNetty框架将网络编程逻辑与业务逻辑处理分离开来,其内部会自动...
    landon30阅读 4,251评论 0 0
  • # Goroutine多线程同步 Goroutine是Go语言特有的并发体,是一种轻量级的线程,由go关键字启动。...
    lixiande阅读 3,214评论 0 0
  • 转载自:超详细的讲解Go中如何实现一个协程池 并发(并行),一直以来都是一个编程语言里的核心主题之一,也是被开发者...
    紫云02阅读 4,717评论 0 1

友情链接更多精彩内容