2021-03-11:go中,协程内部再启用协程,它们是没关系,对吧?外部协程奔溃,内部协程还会执行吗?外部协程执行结束的时候,如何让内部协程也停止运行?golang原生提供的包里,让内部协程停止运行,如何实现?
福哥答案2021-03-11:
1.外部协程和内部协程没关系。
2.如果程序不奔溃,不会影响内部协程继续执行。如果没做特殊处理,整个程序会奔溃。
3.三种方式:共享变量作为标志位,通道,上下文context。这三种方式均是协作式中断,不是抢占式。对于程序员,是无法实现抢占式中断的。
如果能实现抢占式,请发代码,谢谢。
代码用golang编写,代码如下:
package mainimport (\"context\"\"fmt\"\"time\")func main() {input := 0for {fmt.Println(\"1.标志位方式\")fmt.Println(\"2.通道方式\")fmt.Println(\"3.上下文方式\")fmt.Println(\"4.退出\")fmt.Println(\"请输入数字:\")fmt.Scanf(\"%d\", &input)switch input {case 1:go outer1()case 2:go outer2()case 3:go outer3()default:return}time.Sleep(time.Second * 7)}fmt.Scanf(\"%d\", &input)}//1.标志位func outer1() {isInterrupt := falseinner := func() {for {if isInterrupt {fmt.Println(\"inner1 退出\")break} else {fmt.Println(\"inner1 执行中...\")time.Sleep(time.Second * 1)}}}go inner()fmt.Println(\"outer1 等待中... 5s\")time.Sleep(time.Second * 5)isInterrupt = truefmt.Println(\"outer1 退出\")}//2.通道func outer2() {c := make(chan struct{}, 1)inner2 := func() {for {select {case <-c:fmt.Println(\"inner2 退出...\")returndefault:fmt.Println(\"inner2 执行中...\")time.Sleep(time.Second * 1)}}}go inner2()fmt.Println(\"outer2 等待中... 5s\")time.Sleep(time.Second * 5)c <- struct{}{}fmt.Println(\"outer2 退出\")}//3.contextfunc outer3() {ctx, cancel := context.WithCancel(context.Background())inner3 := func() {for {select {case <-ctx.Done():fmt.Println(\"inner3 退出...\")returndefault:fmt.Println(\"inner3 执行中...\")time.Sleep(time.Second * 1)}}}go inner3()fmt.Println(\"outer3 等待中... 5s\")time.Sleep(time.Second * 5)//操作cancel()fmt.Println(\"outer3 退出\")}
执行结果如下:
知乎答案
评论