目录

传统方式

单个goroutine退出

多个goroutine退出

Context包 控制退出

context.WithTimeout 退出

context.WithCanel 退出

context.WithDeadLine 退出

context.WithValue 传值

相关建议约束


传统方式

在刚开始学go的时候,没用过Context包,那么退出携程的方式一般有这么几种

单个goroutine退出

使用携 chan 发送消息通知,这种一般只适合单个goroutine

func exit01() {done := make(chan bool)go func() {for {select {case <-done:fmt.Println("退出携程")returndefault:fmt.Println("监控中...")time.Sleep(1 * time.Second)}}}()time.Sleep(3 * time.Second)done <- truetime.Sleep(5 * time.Second)fmt.Println("程序退出")
}

多个goroutine退出

使用关闭 chan 的方式通知多个goroutine退出

func exit02() {done :=make(chan bool)go func() {for{select {case <-done:fmt.Println("退出携程01")returndefault:fmt.Println("监控01...")time.Sleep(1*time.Second)}}}()go func() {for res :=range done{ //没有消息阻塞状态,chan关闭 for 循环结束fmt.Println(res)}fmt.Println("退出监控03")}()go func() {for{select {case <-done:fmt.Println("退出携程02")returndefault:fmt.Println("监控02...")time.Sleep(1*time.Second)}}}()time.Sleep(3*time.Second)close(done)time.Sleep(5*time.Second)fmt.Println("退出程序")
}

Context包 控制退出

获取 context上下文两种方式

ctx := context.Background() //这只能用于高等级(在 main 或顶级请求处理中)。这能用于派生我们稍后谈及的其他 contextctx := context.TODO()  // 也只能用于高等级或当您不确定使用什么 context,或函数以后会更新以便接收一个 context 

他们的底层实现完全一致,不同的是,静态分析工具可以使用它来验证 context 是否正确传递,
这是一个重要的细节,因为静态分析工具可以帮助在早期发现潜在的错误,并且可以连接到 CI/CD 管道

var (background = new(emptyCtx)todo       = new(emptyCtx)
)

context.WithTimeout 退出

使用context.WithTimeout,主动调用 cancel()方法,可以在时间超时之前退出 goroutine

func exit03() {ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)go func() {for{select {case <-ctx.Done():fmt.Println("退出携程")returndefault:fmt.Println("请求中..")time.Sleep(1*time.Second)}}}()time.Sleep(5*time.Second)//cancel() //也可以手动调用 cancel()方法退出//time.Sleep(2*time.Second)fmt.Println("程序退出")}

context.WithCanel 退出

使用 context.WithCanel()方法,根据外部条件手动调用 cancel()方法退出
只有创建它的函数才能调用取消函数来取消此 context。如果您愿意,可以传递取消函数,但是,强烈建议不要这样做。
这可能导致取消函数的调用者没有意识到取消 context 的下游影响。可能存在源自此的其他 context,
这可能导致程序以意外的方式运行。简而言之,永远不要传递取消函数

func exit04() {ctx, cancel := context.WithCancel(context.Background())go func() {for{select {case <-ctx.Done():fmt.Println("退出携程")returndefault:fmt.Println("监控01")time.Sleep(1*time.Second)}}}()time.Sleep(5*time.Second)cancel()time.Sleep(2*time.Second)fmt.Println("退出程序")}   

context.WithDeadLine 退出

使用 context.WithDeadLine() ,在指定的时间退出 goroutine

func exit05() {stringTime := "2019-08-11 09:08:01"loc, _ := time.LoadLocation("Local")the_time, _ := time.ParseInLocation("2006-01-02 15:04:05", stringTime, loc)ctx, _ := context.WithDeadline(context.Background(), the_time)go func() {for{select {case <-ctx.Done():fmt.Println("退出 goroutine")returndefault:fmt.Println("监控...")time.Sleep(1*time.Second)}}}()time.Sleep(60*time.Second)fmt.Println("程序退出")}

context.WithValue 传值

使用context.WithValue()传值,在所有的context树中都能获取到该值,如果设置相同的key 则覆盖该值
不建议使用 context 值传递关键参数,而是函数应接收签名中的那些值,使其显式化。

func exit06() {ctx := context.WithValue(context.Background(), "msg", "hello word")go func(ctx context.Context) {fmt.Println(ctx.Value("msg"))}(ctx)time.Sleep(2*time.Second)fmt.Println("程序退出")
}

相关建议约束

  • context.Background 只应用在最高等级,作为所有派生 context 的根。
  • context.TODO 应用在不确定要使用什么的地方,或者当前函数以后会更新以便使用 context。
  • context 取消是建议性的,这些函数可能需要一些时间来清理和退出。
  • context.Value 应该很少使用,它不应该被用来传递可选参数。这使得 API 隐式的并且可以引起错误。取而代之的是,这些值应该作为参数传递。
  • 不要将 context 存储在结构中,在函数中显式传递它们,最好是作为第一个参数。
  • 永远不要传递不存在的 context 。相反,如果您不确定使用什么,使用一个 ToDo context。
  • Context 结构没有取消方法,因为只有派生 context 的函数才应该取消 context。

golang goroutine 退出方法相关推荐

  1. golang goroutine 协程原理

    一.goroutine简介 goroutine是go语言中最为NB的设计,也是其魅力所在,goroutine的本质是协程,是实现并行计算的核心.goroutine使用方式非常的简单,只需使用go关键字 ...

  2. goroutine退出方式的总结

    goroutine的退出机制 大家都知道goroutine是Go语言并发的利器,通过goroutine我们可以很容易的编写高并发的程序.但是goroutine设计的退出机制是由goroutine自己退 ...

  3. centos使用镜像源轻松配置golang+vscode的方法

    Title:centos使用镜像源轻松配置golang+vscode的方法 (阅读时间:约5分钟) 零.序言 最近笔者在上一门名为服务计算的课程,在老师的作业博客中提到,安装golang+vscode ...

  4. winform关闭当前form_C#中WinForm程序退出方法技巧总结

    C#中WinForm程序退出方法技巧总结 一.关闭窗体 在c#中退出WinForm程序包括有很多方法,如:this.Close(); Application.Exit();Application.Ex ...

  5. java超时自动关闭_[Java教程]web页面超时自动退出方法_星空网

    web页面超时自动退出方法 2017-05-18 0 思路: 使用 mousemover 事件来监测是否有用户操作页面,写一个定时器间隔特定时间检测是否长时间未操作页面,如果是,退出: 具体时间代码如 ...

  6. python 退出自定义函数_python通过自定义异常,提前退出方法

    python退出的操作,搜索后都是return.exit()等 return:退出一个方法,并返回一个值 exit():退出python 想要实现的功能: 方法A中调用多个方法,方法B.方法C..., ...

  7. python退出交互_python交互界面的退出方法

    python交互界面的退出方法 1.在终端输入python,进入之后退出: quit() 或者 exit() 2,进入idle shell下的退出 关闭: quit() 或者 exit() 或者快捷键 ...

  8. oracle怎么退出,[转载]Oracle 11g SQL*Plus的几种启动、退出方法

    SQL*Plus是与Oracle数据库进行交互的一个非常重要.在服务器端或客户端都可以使用的工具,同时也是一个通用的.在各种平台上几乎都完全一致的工具.所以SQL*Plus的应用非常广泛.而且初学者基 ...

  9. Linux IV ,IVM编辑 退出方法

    IV ,IVM编辑 退出方法 :WQ   保存退出 :X :Q    不保存退出 U撤销,ctrl+R 恢复.

最新文章

  1. gprof 性能优化工具
  2. 火狐拓展开发 基础知识
  3. N-MOS的G-S电容随着DS电压的变化关系
  4. 你要的人工智能答案,在这里!
  5. python如何读取excel数据-使用Python读取电子表格中的数据
  6. linux下nginx与php设置开机启动代码
  7. js-ajax-04
  8. python中感叹号_C#中感叹号(!) 的作用总结
  9. [css] 如何解决css加载字体跨域的问题?
  10. $(document).scrollTop()与$(window).scrollTop()
  11. Swift - 推送之本地推送(UILocalNotification)添加Button的点击事件
  12. Android保存之SharedPreferences
  13. idea上安卓 Android SDK的安装
  14. OpenCV-图像处理(25、直方图比较)
  15. 远程 mysql error 2003_远程连接MySQL报错ERROR 2003解决办法
  16. 乌班图/Ubuntu 21.10 安装nvidia 显卡驱动
  17. DllMain 参数解释
  18. 地铁bas服务器系统,地铁BAS系统构成及工作原理
  19. T216909 小卡与质数2 (前缀和 欧拉筛
  20. MOSFET驱动电路总结

热门文章

  1. Windows Server 2012 存储 (四) SMB 对SQL 数据库和Hyper-V的支持
  2. silverlight学习布局之:布局stackpanel
  3. 一个关于解决序列化问题的编程技巧
  4. python数据可视化库 动态的_python --数据可视化(一)
  5. 云计算与云原生技术系列文章
  6. Python 进阶_函数式编程
  7. zoj4110 Strings in the Pocket(manacher)
  8. Atitit. 软件GUIbutton与仪表盘--webserver区--获取apache配置文件路径 linux and apache的启动、停止、重新启动...
  9. python迭代器和生成器(3元运算,列表生成式,生成器表达式,生成器函数)
  10. open*** 启动报错