• 2021-03-11:go中,协程内部再启用协程,它们是没关系,对吧?外部协程奔溃,内部协程还会执行吗?外部协程执行结束的时候,如何让内部协程也停止运行?golang原生提供的包里,让内部协程停止运行,如何实现?


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

    执行结果如下:
    在这里插入图片描述


    知乎答案
    评论

  • 相关阅读:
    发红包案列——继承和集合
    抽象类
    方法重写
    继承——访问成员变量,访问成员方法,访问构造方法
    js异步计时器
    栈(stack)和堆(heap)
    高并发和多线程概念
    集群、负载均衡、分布式、微服务
    Redis性能监控
    Redis配置
  • 原文地址:https://www.cnblogs.com/waitmoon/p/14520370.html
Copyright © 2020-2023  润新知