怎么关闭golang协程

这篇文章给大家分享的是关闭golang协程的方法。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。

1、通过Channel传递退出信号

channel作为go的一种基本数据类型,它有3种基本状态:nil、open、closed。

通过Channel共享数据,而不是通过共享内存共享数据。主流程可以通过channel向任何goroutine发送停止信号,就像下面这样:

func run(done chan int) {
        for {
                select {
                case <-done:
                        fmt.Println("exiting...")
                        done <- 1
                        break
                default:
                }
 
                time.Sleep(time.Second * 1)
                fmt.Println("do something")
        }
}
 
func main() {
        c := make(chan int)
 
        go run(c)
 
        fmt.Println("wait")
        time.Sleep(time.Second * 5)
 
        c <- 1
        <-c
 
        fmt.Println("main exited")
}

2、使用waitgroup

通常情况下,我们像下面这样使用waitgroup:

1、创建一个Waitgroup的实例,假设此处我们叫它wg

2、在每个goroutine启动的时候,调用wg.Add(1),这个操作可以在goroutine启动之前调用,也可以在goroutine里面调用。当然,也可以在创建n个goroutine前调用wg.Add(n)

3、当每个goroutine完成任务后,调用wg.Done()

4、在等待所有goroutine的地方调用wg.Wait(),它在所有执行了wg.Add(1)的goroutine都调用完wg.Done()前阻塞,当所有goroutine都调用完wg.Done()之后它会返回。

示例:

type Service struct {
        // Other things
 
        ch        chan bool
        waitGroup *sync.WaitGroup
}
 
func NewService() *Service {
	s := &Service{
                // Init Other things
                ch:        make(chan bool),
                waitGroup: &sync.WaitGroup{},
	}
 
	return s
}
 
func (s *Service) Stop() {
        close(s.ch)
        s.waitGroup.Wait()
}
 
func (s *Service) Serve() {
        s.waitGroup.Add(1)
        defer s.waitGroup.Done()
 
        for {
                select {
                case <-s.ch:
                        fmt.Println("stopping...")
                        return
                default:
                }
                s.waitGroup.Add(1)
                go s.anotherServer()
	}
}
func (s *Service) anotherServer() {
        defer s.waitGroup.Done()
        for {
                select {
                case <-s.ch:
                        fmt.Println("stopping...")
                        return
                default:
                }
 
                // Do something
        }
}
 
func main() {
 
        service := NewService()
        go service.Serve()
 
        // Handle SIGINT and SIGTERM.
        ch := make(chan os.Signal)
        signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
        fmt.Println(<-ch)
 
        // Stop the service gracefully.
        service.Stop()
}

关于关闭golang协程的方法就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

原创文章,作者:CGZBG,如若转载,请注明出处:https://www.beidanyezhu.com/a/26114.html

(0)
CGZBG的头像CGZBG
上一篇 2024-12-17 14:10:17
下一篇 2025-01-01 17:24:57

相关推荐

  • golang中导入包的方法

    这篇文章运用简单易懂的例子给大家介绍golang中导入包的方法,代码非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。 import Go 使用包(package)作为…

  • 如何升级golang的版本

    升级Golang 主要步骤: 1、卸载旧版本 2、下载新版本 3、安装新版本 4、配置环境变量 详细步骤: 1、卸载旧版本 首先,执行 go env,列出关于go的环境信息,查看 …

  • Golang实现REST API架构

    有一种说法,golang 编写的 API 不能像其他语言那样简单和通用。但实际上,我遇到很多 REST API 的代码,非常多的抽象,使得代码库变得混乱和复杂,最终伤害了可读性和可…

    2025-01-03
  • golang有哪些数据类型

    这期内容当中小编将会给大家带来有关golang有哪些数据类型,以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。 在 Go 编程语言中,数据类型用于声明函数和变量。…

  • golang是什么

    golang是什么?针对这个问题,这篇文章给出了相对应的分析和解答,希望能帮助更多想解决这个问题的朋友找到更加简单易行的办法。 Go(又称Golang)是Google开发的一种静态…

  • 如何用golang实现约瑟夫环

    约瑟夫环概念: 约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从…

    2025-01-02
  • golang的字符串操作

    Go语言简介 Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。 罗伯特·格瑞史莫(Robert Griesemer),罗勃…

  • golang中的链接link是什么

    链接(link) 我们编写的程序可能会使用其他程序或程序库( library ) 正如我们在helloworld程序中使用的fmt package 我们编写的程序必须与这些程序或程…

  • golang的内存分配

    本篇文章主要介绍golang的内存分配,文中关于内存分配的算法以及mcache的介绍均以实例展示,有需要的朋友可以参考一下。 程序内存大致可以分为5个段text、data、bss、…

    2025-01-01
  • golang中gopath的介绍

    这篇文章主要介绍了golang中gopath工具,具有一定借鉴价值,需要的朋友可以参考下。如下资料是关于gopath的详细步骤内容。 前言 在本章中,我们将介绍go语言的项目结构、…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

分享本页
返回顶部