GoLang使goroutine停止的五种方法实例

作者:GoGo在努力 时间:2023-09-02 08:31:33 

GoLang之使goroutine停止的5种方法

1.goroutine停止介绍

goroutine是Go语言实现并发编程的利器,简单的一个指令go function就能启动一个goroutine;

但是,Go语言并没有提供终止goroutine的接口,也就是说,我们不能从外部去停止一个goroutine,只能由goroutine内部退出(main函数终止除外);

我们有很多情况下需要主动关闭goroutine,如需要实现一个系统自动熔断的功能就需要主动关闭goroutine

2.goroutine停止的5种方法

2.1使用for-range

for-range从channel上接收值,直到channel关闭,该结构在Go并发编程中很常用,这对于从单一通道上获取数据去执行某些任务是十分方便的

GoLang使goroutine停止的五种方法实例

GoLang使goroutine停止的五种方法实例

2.2使用for-select(向退出通道发出退出信号)

当channel比较多时,for-range结构借不是很方便了;

Go语言提供了另外一种和channel相关的语法: select;

select能够让goroutine在多个通信操作上等待(可以理解为监听多个channel);

由于这个特性,for-select结构在Go并发编程中使用的频率很高;

我在使用Go的开发中,这是我用的最多的一种组合形式:

for {<!--{C}%3C!%2D%2D%20%2D%2D%3E-->
select {<!--{C}%3C!%2D%2D%20%2D%2D%3E-->
}
}

对于for-select结构,一般我会定义一个特定的退出通道,用于接收退出的信号,如quit

GoLang使goroutine停止的五种方法实例

2.3使用for-select(关闭退出通道)

当我们就需要向quit通道中发送100次数据,如果再用以上的代码就很麻烦,有一个很简单的方法,关闭channel,这样所有监听quit channel的goroutine就都会收到关闭信号,上面的代码只要做一个很小的替换就能工作

GoLang使goroutine停止的五种方法实例

2.4使用for-select(关闭多个channel)

如果select上监听了多个通道,需要所有的通道都关闭后才能结束goroutine,这里就利用select的一个特性,select不会在nil的通道上进行等待,因此将channel赋值为nil即可,此外,还需要利用channel的ok值

var wg sync.WaitGroup
func worker(in1, in2 <-chan int) {
defer wg.Done()
for {
select {
case v, ok := <-in1:
if !ok {
fmt.Println("收到退出信号")
in1 = nil
}
// do something
fmt.Println(v)
case v, ok := <-in2:
if !ok {
fmt.Println("收到退出信号")
in2 = nil
}
// do something
fmt.Println(v)
}
// select已经结束,我们需要判断两个通道的状态
// 都为nil则结束当前goroutine
if in1 == nil && in2 == nil {
return
}
}
}
func main() {
in1 := make(chan int) // 退出通道,接收
in2 := make(chan int)
wg.Add(2)
go worker(in1, in2)
go worker(in2, in2)
for i := 0; i < 3; i++ {
in1 <- i
time.Sleep(1 * time.Second)
in2 <- i
}
close(in1)
close(in2)
wg.Wait()
}

GoLang使goroutine停止的五种方法实例

2.5使用context包

context包是官方提供的一个用于控制多个goroutine写作的包;

使用context的cancel信号,可以终止goroutine的运行,context是可以向下传递的

来源:https://blog.csdn.net/weixin_52690231/article/details/123159765

标签:golang,goroutine,停止
0
投稿

猜你喜欢

  • 关于Youtube URL的十个技巧

    2009-04-21 13:19:00
  • 用基于python的appium爬取b站直播消费记录

    2021-08-03 21:57:23
  • numpy的sum函数的axis和keepdim参数详解

    2021-08-02 02:48:46
  • SQL 无法装载DLL Microsoft原因(无法修改sa密码)

    2024-01-19 21:04:57
  • Sql Server 2005读取外部数据的方法

    2008-07-08 19:08:00
  • C#访问PostGreSQL数据库的方法

    2024-01-23 01:00:13
  • php多个文件及图片上传实例详解

    2024-05-22 10:06:28
  • python使用pandas处理excel文件转为csv文件的方法示例

    2021-09-13 07:15:52
  • Oracle 10G:PL/SQL正规表达式(正则表达式)手册

    2009-07-02 12:33:00
  • python实现随机密码字典生成器示例

    2022-07-25 17:11:50
  • Pyqt实现无边框窗口拖动以及窗口大小改变

    2023-07-30 01:59:10
  • python实现大量图片重命名

    2023-12-26 07:20:56
  • Python中的Nonetype类型怎么判断

    2021-06-19 17:33:13
  • 使用MySQL内建复制功能

    2009-12-15 21:36:00
  • 原生JS实现Ajax通过POST方式与PHP进行交互的方法示例

    2023-09-07 22:44:41
  • Python3连接Mysql8.0遇到的问题及处理步骤

    2024-01-20 13:06:46
  • python的pstuil模块使用方法总结

    2022-10-09 22:47:16
  • 解决matplotlib.pyplot在Jupyter notebook中不显示图像问题

    2022-03-03 14:55:10
  • Appium自动化测试中获取Toast信息操作

    2022-05-12 07:10:48
  • 跟我学习javascript的闭包

    2024-04-23 09:11:51
  • asp之家 网络编程 m.aspxhome.com