一个简单的go小问题解释

屏幕快照 2020-01-17 下午6.02.51.png

屏幕快照 2020-01-17 下午6.02.54.png

一个简单的小代码, 上面是代码, 下面是结果

我很奇怪, 为什么这边的协程还是能打印, 主线程不是已经结束了嘛? Test46已经调用结束, 像这种go新开的协程的生命周期是根据什么来的呢

阅读 1.6k
评论
    4 个回答

    你使用了gin服务器,还开启了监听,主线程并没有结束。
    要学习协程的话,开新项目,不需要任何依赖。

    评论 赞赏

      因为框架内,启动了一个http服务,阻塞的。主线程永远不会停的

      评论 赞赏
        Atey
        • 227

        在 web 框架内开 goroutine, 建议严格控制 goroutine 的生命周期, 防止大量无用 goroutine 产生...

        评论 赞赏

          问题一:主线程不是已经结束了吗?

          没有结束。你的 api 不是还可以正常访问的嘛。你关闭 gin 启动的 HTTP 服务后就算结束。这个被称为 主goroutine。

          问题二:goroutine (协程) 生命周期是根据什么来的呢?

          首先了解一下 Go 语言并发编程模型,以及用户级线程 goroutine ,还有强大的用于调度 goroutine 和 系统级线程对接的调度器。Go 并发编程模型主要由三个主要元素组成:G(goroutine)、P(processor)、M(machine)

          G:一个 G 代表一个 go 代码片段,多个 G 组成一个本地队列(Local Queue)
          P:一个 P 代表执行一个 Go 代码片段所必须要的资源(上下文环境)
          M:一个 M 代表一个内核线程(工作线程)

          三者关系图
          “golang GMP”的图片搜索结果

          从上图中可以看出,一个 M 在其生命周期内,M 与 KSE(内核调度实体)之间是(确定关联)一对一关系。相比之下,P、G 二者的关联都是易变的(可能关联),它们之间的关系会在实际调度过程中发生变更;但是 M 与 P 之间也总是一对一的,P 与 G 之间是一对多的关系。此外,M 与 G之间也会简历关联,因为一个 G 终归会由一个 M 来负责运行,它们之间的关联会由 P 来牵线。

          了解上面这个知识点后好想还是没弄明白它真正的生命周期,要想进一步了解推荐阅读 大左 老师的 Go 语言调度器,它对其创建 Goroutine、调度循环、触发调度及线程管理讲解十分透彻。

          评论 赞赏
            撰写回答

            登录后参与交流、获取后续更新提醒