IT评测·应用市场-qidao123.com

标题: 如何优雅得关闭协程呢 [打印本页]

作者: 麻花痒    时间: 2023-5-14 11:27
标题: 如何优雅得关闭协程呢
1.简介

本文将介绍首先为什么需要主动关闭goroutine,并介绍如何在Go语言中关闭goroutine的常见套路,包括传递终止信号和协程内部捕捉终止信号。之后,文章列举了需要主动关闭协程运行的常见场景,如启动一个协程执行一个不断重复的任务。希望通过本文的介绍,读者能够掌握如何在适当的时候关闭goroutine,以及了解关闭goroutine的常见套路。
2.为什么需要关闭goroutine

2.1 协程的生命周期

了解协程的生命周期是优雅地关闭协程的前提,因为在关闭协程之前需要知道协程的当前状态,以便采取相应的措施。所以这里我们需要先了解下goroutine的生命周期。
在 Go语言中,协程(goroutine)是一种轻量级的线程,可以在一个程序中同时运行多个协程,提高程序的并发性能。协程的生命周期包括创建、运行和结束三个阶段。
首先需要创建一个协程,协程的创建可以通过关键字 go 来实现,例如:
  1. go func() {
  2.     // 协程执行的代码
  3. }()
复制代码
上面的代码会启动一个新的协程,同时在新的协程中执行匿名函数,此时协程便已被创建了。
一旦协程被创建,它就会在新的线程中运行。协程的运行状态可以由 Go 运行时(goroutine scheduler)来管理,它会自动将协程调度到适当的P中运行,并确保协程的公平调度和平衡负载。
在运行阶段,协程会不断地执行任务,直到任务完成或者遇到终止条件。在终止阶段,协程将会被回收,从而完成其整个生命周期。
综上所述,协程由go关键字启动,在协程中执行其业务逻辑,直到最后遇到终止条件,此时代表着协程的任务已经结束了,将进入终止阶段。最终协程将会被回收。
2.2 协程的终止条件

正常来说,都是协程任务执行完成之后,此时协程自动退出,例如:
  1. func main() {
  2.    var wg sync.WaitGroup
  3.    wg.Add(1)
  4.    go func() {
  5.       defer wg.Done()
  6.       // 协程执行的代码
  7.       fmt.Println("协程执行完毕")
  8.    }()
  9.    wg.Wait()
  10.    // 等待协程执行完毕
  11.    fmt.Println("主程序结束")
复制代码
上面的代码中,我们使用 WaitGroup 等待协程执行完毕。在协程执行完毕后,程序会输出协程执行完毕和主程序结束两条信息。
还有一种情况是协程发生panic,它将会自动退出。例如:
  1. func main() {
  2.     var wg sync.WaitGroup
  3.     wg.Add(1)
  4.     go func() {
  5.         defer wg.Done()
  6.         // 协程执行的代码
  7.         panic("协程发生错误")
  8.     }()
  9.     // 等待协程执行完毕
  10.     wg.Wait()
  11.     fmt.Println("主程序结束")
  12. }
复制代码
在这种情况下,协程也会自动退出,不会再占用系统资源。
综合看来,协程的终止条件,其实就是协程中的任务执行完成了,或者是执行过程中发生了panic,协程将满足终止条件,退出执行。
2.3 为什么需要主动关闭goroutine

从上面协程的终止条件来看,正常情况下,协程只要将任务正常处理完成,协程自动退出,此时并不需要主动关闭goroutine。
这里先举一个生产者消费者的例子,在这个例子中,我们创建了一个生产者和一个消费者,它们之间通过一个channel进行通信。生产者生产数据并发送到一个channel中,消费者从这个channel中读取数据并进行处理。代码示例如下:
[code]func main() {    // 生产者代码    go func(out chan




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4