关于go在函数退出后子协程的退出问题
生活随笔
收集整理的這篇文章主要介紹了
关于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:} }遇到該問題后,我寫了幾個測試:
單純的函數退出,是不會影響協程的
我經常在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在函数退出后子协程的退出问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue 解决重复点击导航路由报错 问题
- 下一篇: 解决运行qmake:Project ER