天天看点

2021-03-11:go中,协程内部再启用协程,它们是没关系,对吧?...

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 退出")
}           

复制

执行结果如下:

2021-03-11:go中,协程内部再启用协程,它们是没关系,对吧?...

在这里插入图片描述