关于go在函数退出后子协程的退出问题
关于go在函数退出后子协程的退出问题
该问题来源于自己在读fabric源码时,看到的一个测试代码,在一个函数中启用协程,然后该函数退出了,由于平常没有这样处理过,以及受原有c++函数域的影响,认为函数退出,子协程应该也退出了呀。
这其实是自己对go协程的理解不到位引起的,go的协程作用域不是在某个函数中的,当然,如果那个函数是main函数,就符合要求了。
该代码为solo算法的测试代码:
func goWithWait(target func()) *waitableGo {wg := &waitableGo{done: make(chan struct{}),}go func() {target()//该协程会阻塞在这close(wg.done)//用来对外通知}()//外边结束,里边还不结束吗?return wg
}
// This test checks that if consenter is halted before a timer fires, nothing is actually written.
func TestHaltBeforeTimeout(t *testing.T) {batchTimeout, _ := time.ParseDuration("1ms")//support的构造还不清楚support := &mockmultichannel.ConsenterSupport{Blocks: make(chan *cb.Block),BlockCutterVal: mockblockcutter.NewReceiver(),SharedConfigVal: &mockconfig.Orderer{BatchTimeoutVal: batchTimeout},}defer close(support.BlockCutterVal.Block)bs := newChain(support)//bs.main是solo算法的启动函数,是个死循环,处理函数wg := goWithWait(bs.main)defer bs.Halt()//中止syncQueueMessage(testMessage, bs, support.BlockCutterVal)bs.Halt()select {case <-support.Blocks:t.Fatalf("Expected no invocations of Append")case <-wg.done:}
}
遇到该问题后,我写了几个测试:
单纯的函数退出,是不会影响协程的
package mainimport "fmt"var ch chan intfunc test() int {ch = make(chan int)go func() {for {fmt.Println(<-ch)fmt.Println("hello")}fmt.Println("aaaa")}()//不阻塞,那go func()不会异常退出吗?//协程并不是函数,不会因为这个函数的退出而退出//test()启动一个deadloop子协程,这个会在主协程main结束后被强制退出return 0
}
func main() {c := test()ch <- 10fmt.Println("c", c)
}
我经常在main里边直接写协程的测试demo,main退出会结束主协程,之后会强制结束子协程,一般不会遇到上述在普通函数退出的问题,也没仔细思考,所以分析源码时有点困惑。
子协程启动子协程,父协程的退出,并没有影响到子协程
liudeMacBook-Pro:~ liu$ cat tmp.go
package main
import ("fmt""time"
)
func test() {go func() { //父协程defer func() {fmt.Println("exit dad")}()go func() { //子协程defer func() {fmt.Println("exit kid")}()}()}()
}
func main() {test()time.Sleep(time.Second)
}
liudeMacBook-Pro:~ liu$ go run tmp.go
exit dad
exit kid
关于go在函数退出后子协程的退出问题相关推荐
- go语言之进阶篇主协程先退出导致子协程没来得及调用
1.主协程先退出导致子协程没来得及调用 示例: package mainimport ("fmt""time" )//主协程退出了,其它子协程也要跟着退出 fu ...
- python中协程与函数的区别_python 协程与go协程的区别
进程.线程和协程 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定义: 操作系统能够进行运算调度的最小单位.它被包含在进 ...
- go 怎么等待所有的协程完成_优雅地等待子协程执行完毕
goroutine模拟了线程级别的返场的能力,但它的执行需要主协程给机会.一般的作法用sleep,chan阻塞,看起来让人不爽,本文介绍sync.WaitGroup 类型结合 defer 的特性,给出 ...
- Go 知识点(10) — 子协程能否使用主协程变量
我们来看这样一个问题,在主协程中创建的变量,在子协程中能否使用?来看下面代码: func main() {s := "hello"fmt.Printf("s outsid ...
- python中协程与函数的区别_python协程和异步IO
1.并发.并行.同步.异步.阻塞.非阻塞 并发:是指在同一个时间段内,有几个程序都处于启动运行到运行结束之间 并行:在同一个时间点上,有几个程序同时运行 同步:当一个同步操作发出去后,调用者一直等待返 ...
- Go 知识点(01)— 主协程与子协程执行顺序
下面代码的输出结果是什么? package mainimport ("fmt" )func main() {for i := 0; i < 10; i++ {go func( ...
- android自动退出对话框,Android开发 在用EditText对话框Dialog退出后实现输入盘的退出...
前言 在使用继承的Dialog的方式实现自定义Dialog,如果这个Dialog我们还添加了EditText就会发现一个问题.在输入盘显示后,Dialog退出输入盘不会退出.网上有一些奇怪的解决办法, ...
- macbook的 safari浏览器退出后又自动启动,强制退出以后也重启,重启电脑也重启
如图所示: 原来进程是被这个叫**.Yahoo.plist的文件一直在占用运行,前面红圈是进程的PID,只要使用(kill -9 PID)杀死进程就可以了. 2.先去截图中所示的 ~/Library/ ...
- 千军万马跑协程goroutine
参考:<快学 Go 语言>第 11 课 -- 千军万马跑协程 - 云+社区 - 腾讯云 协程和通道是 Go 语言作为并发编程语言最为重要的特色之一,初学者可以完全将协程理解为线程,但是用起 ...
最新文章
- 代码攻击破坏设备,炸毁 27 吨发电机的背后
- 51nod1228 序列求和(伯努利数)
- UnityVS(Visual Studio Tools For Unity)的安装与使用
- php Session存储到Redis的方法
- (3)段描述符,段选择子,LES指令
- python中的set类型
- MySQL COUNT函数优化及count(1)/count(*)/count(列名)的区别
- 小米小爱蓝牙音箱_小米小爱蓝牙音箱——值否?
- samba安装_Centos安装Samba
- java 守护线程 作用_java中守护线程的一些概念和用法
- FileZilla Server远程管理
- OSI七层协议完美解读
- 【协同任务】基于matlab蚁群算法多组群UAV协同任务路径规划【含Matlab源码 1578期】
- 交叉编译工具链的安装和配置过程
- mac苹果画图软件_苹果Mac绘图软件 OmniGraffle for Mac v7.15.1 中文免费版
- 电子邮箱格式什么样的好?什么邮箱好用?
- 读侯世达之《哥德尔、艾舍尔、巴赫:集异壁之大成》
- 全球创见者共话企业韧性 金蝶“数字员工”惊艳亮相
- rknn模型转换问题记录
- PDF文件如何编辑?这两种方法是我一直在用的
热门文章
- 《An Industrial-Strength Audio Search Algorithm》译文
- Kubernetes 进阶训练营 Pod基础
- Beacon学习总结
- 光纤收发器指示灯的意义图解
- 從turtle海龜動畫 學習 Python - 高中彈性課程系列 10.2 藝術畫 Python 製作生成式藝術略覽
- 深度神经网络对人工智能推动的发展评述与应用分析
- 764. 最大加号标志
- win7 nvme 支持补丁_国产桌面版OS系统发布:Win7般体验 最高安全认证
- 请收下,700+页PDF社区精化!
- python3 模拟 ajax post请求