当前位置: 首页 > news >正文

go语言-用channel控制goroutine的退出

用channel控制goroutine的退出

本文简要介绍了,如何用channel控制goroutine的退出的基本方法

for-range主动停止goruitine

package mainimport ("fmt""sync""time"
)/*
Go并发编程模型:主动停止goroutine
方法一:for-rang从channel上接收值,直到channel关闭
*/
var wg sync.WaitGroupfunc work(ch chan int) {defer wg.Done()// for range关键字,将其使用在channel上时,会自动等待channel的动作一直到channel被关闭close// 也就是clase(sh)后,for range就会退出for i := range ch {fmt.Println(i)}fmt.Println("work exit")
}func main() {wg.Add(1)var ch chan intch = make(chan int)go work(ch)for i := 0; i < 3; i++ {time.Sleep(1 * time.Second)ch <- i}time.Sleep(3 * time.Second)for i := 4; i < 7; i++ {time.Sleep(1 * time.Second)ch <- i}// close(sh)来控制"work"协程中的for range的完成close(ch)wg.Wait()
}

后台定时任务

	// 设定一个定时器,当定时器触发是就执行一次任务tricker := time.NewTicker(1 * time.Second)defer fmt.Println("tricker.Stop()")defer tricker.Stop()for {select {case <-stopCh:fmt.Println("do1 exit.")return//心跳,心跳一次就执行一次任务case <-tricker.C:time.Sleep(1 * time.Second)fmt.Println("do1 doing....")}}

使用stopCh控制goroutine退出

package mainimport ("fmt""sync""time"
)var wg sync.WaitGroupfunc do1(stopCh chan struct{}) {defer wg.Done()for {select {case <-stopCh:fmt.Println("go1 exit.")returndefault:time.Sleep(1 * time.Second)fmt.Println("go1 doing....")}}
}
func do2(stopCh chan struct{}) {defer wg.Done()for {select {case <-stopCh:fmt.Println("go2 exit.")returndefault:time.Sleep(1 * time.Second)fmt.Println("go2 doing....")}}
}func main() {wg.Add(2)stopCh := make(chan struct{})go do1(stopCh)go do2(stopCh)time.Sleep(5 * time.Second)// 让一个goroutine退出stopCh <- struct{}{}time.Sleep(5 * time.Second)// 让另一个goroutine退出stopCh <- struct{}{}wg.Wait()}

关闭channel来控制goroutine退出

package mainimport ("fmt""sync""time"
)/*
多个通道都关闭才退出
利用select的一个特性,select不会在nil的通道上进行等待
*/
var wg sync.WaitGroupfunc work(in, exit1, exit2 chan bool) {defer wg.Done()for {select {// 当exit管道收到信号后退出goroutinecase v := <-exit1:fmt.Println("exit1 收到退出信号")fmt.Println("v=", v)exit1 = nilcase <-exit2:fmt.Println("exit2 收到退出信号")exit2 = nilcase value := <-in:fmt.Println(value)}fmt.Println(time.Now())fmt.Println("遍历了一次")// 当2个退出通道都收到信号时,就退出for循环if exit1 == nil && exit2 == nil {return}}}func main() {in := make(chan bool)exit1 := make(chan bool)exit2 := make(chan bool)wg.Add(1)go work(in, exit1, exit2)for i := 0; i < 6; i++ {time.Sleep(5 * time.Millisecond)in <- true}// 主动停止goroutine方法一//exit1 <- 1//exit2 <- 1// 主动停止goroutine方法二close(exit1)close(exit2)wg.Wait()}
http://www.lryc.cn/news/292603.html

相关文章:

  • 强大的虚拟机Parallels Desktop 19 mac中文激活
  • 单元测试框架深入(一):单元测试框架深入
  • 苏门X学士常识学习
  • MD5算法:高效安全的数据完整性保障
  • JavaScript基础五对象 内置对象 Math.random()
  • curl之网络接口
  • Pytest中doctests的测试方法应用
  • Android 8.1 铃声音量通话音量同步调节
  • C++——字符串string
  • HBuilder使用[微信小程序开发者工具] 显示 × initialize报错
  • 洛谷P8599 [蓝桥杯 2013 省 B] 带分数
  • grafana安装DevOpsProdigy KubeGraf 1.5.2
  • 大数据 - Hadoop系列《三》- MapReduce(分布式计算引擎)概述
  • 了解Ansible自动化运维工具及模块的使用
  • sql指南之null值用法
  • 常见消息队列:ActiveMQ、RabbitMQ、RocketMQ、Kafka的区别总结
  • 火柴人大逃亡
  • AI革命新篇章:法国天才团队挑战ChatGPT霸主地位
  • 数据双向绑定v-modal
  • Docker 容器jar 运行报错 at sun.awt.FontConfiguration.getVersion 解决方法
  • 光学3D表面轮廓仪服务超精密抛光技术发展
  • 详解C++中auto关键字
  • 24.云原生ArgoCD高级之数据加密seale sealed
  • 线性代数:线性方程组
  • 标准的排序组合-算法
  • 2402C++,C++递归取各种节点名字
  • Qt 5.9.4 转 Qt 6.6.1 遇到的问题总结(三)
  • Logstash 7.7.1版本安装系统梳理
  • 4. sass实用函数归纳
  • 《元梦之星》赛季更新带来“新”内容,为何却被玩家集体声讨?