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