一个简单的小代码, 上面是代码, 下面是结果
我很奇怪, 为什么这边的协程还是能打印, 主线程不是已经结束了嘛? Test46已经调用结束, 像这种go新开的协程的生命周期是根据什么来的呢
###你使用了gin服务器,还开启了监听,主线程并没有结束。
要学习协程的话,开新项目,不需要任何依赖。
因为框架内,启动了一个http服务,阻塞的。主线程永远不会停的
###在 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 代表一个内核线程(工作线程)
三者关系图
从上图中可以看出,一个 M 在其生命周期内,M 与 KSE(内核调度实体)之间是(确定关联)一对一关系。相比之下,P、G 二者的关联都是易变的(可能关联),它们之间的关系会在实际调度过程中发生变更;但是 M 与 P 之间也总是一对一的,P 与 G 之间是一对多的关系。此外,M 与 G之间也会简历关联,因为一个 G 终归会由一个 M 来负责运行,它们之间的关联会由 P 来牵线。
了解上面这个知识点后好想还是没弄明白它真正的生命周期,要想进一步了解推荐阅读 大左 老师的 Go 语言调度器,它对其创建 Goroutine、调度循环、触发调度及线程管理讲解十分透彻。