Go 主协程退出,子协程还在么?

4,779 阅读1分钟

「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战

单元测试行命令说明

用例代码:

import "testing"
func TestHelloWorld(t *testing.T) {
    t.Log("hello world")
}

测试命令

go test helloworld_test.go

运行结果:

ok          command-line-arguments        0.003s

测试命令2 :

go test -v helloworld_test.go

测试命令3 :

 go test -v -run TestHelloWorld helloworld_test.go

基准测试

单纯函数退出,会不会影响子协程?

代码示例:

func 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 TestGrountine(t *testing.T) {
	c := test()
	fmt.Println("c", c)
	ch <- 10 // 塞一个数
}

先把 死循环注释掉, 执行命令

 go test -v grountine_test.go

运行结果如下:

=== RUN   TestGrountine
c 0
10
hello
aaaa
--- PASS: TestGrountine (0.00s)
PASS

如果把死循环加上, 结果如下:

=== RUN   TestGrountine
10
hello
c 0
--- PASS: TestGrountine (0.00s)

启动一个deadloop子协程,这个会在主协程结束后被强制退出。

子协程启动子协程,父协程的退出,并没有影响到子协程

测试程序:

func test1() {
	go func() {
		//父协程
		defer func() {
			fmt.Println("exit dad")
		}()
		go func() {
			//子协程
			defer func() {

				fmt.Println("exit kid")
			}()
		}()
	}()
}
func TestGrountine_2(t *testing.T) {
	test1()
	time.Sleep(time.Second)
}

执行结果:

=== RUN   TestGrountine_2
exit dad
exit kid
--- PASS: TestGrountine_2 (1.00s)
PASS
ok      command-line-arguments  1.033s

可以看到 主程序运行完了 打出exit dad, 子程序也会打出 exit kid 主协程的退出没有影响到子协程。

参考资料