go中协程的生命周期

embedded/2025/1/15 1:18:47/

在 Go 中,协程(goroutine)的生命周期大致可以分为以下几个阶段:

1. 创建阶段

协程的创建通常是通过 go 关键字来启动的。例如:

go func() {// 协程执行的代码
}()

当执行 go func() 时,Go 会在后台启动一个新的协程,新的协程会并发执行传入的函数体。协程是由 Go 的调度器来管理的,调度器负责在多个协程之间进行切换。

2. 运行阶段

协程创建后会进入运行阶段,它会由 Go 的调度器分配一个操作系统线程来执行。协程的执行并不一定是立即开始的,具体的执行顺序由调度器控制。调度器会在所有正在执行的协程之间公平地分配 CPU 时间片。

3. 阻塞阶段

协程可能会在运行时进入阻塞状态,常见的阻塞情况有:

  • 等待 I/O 操作(例如文件读取、网络请求等)
  • 等待锁(例如 sync.Mutex
  • 等待通道操作(例如 chan 的发送或接收)

当协程遇到这些阻塞情况时,Go 的调度器会把该协程挂起,并分配 CPU 时间给其他可以运行的协程。

4. 结束阶段

协程的执行将一直持续到它所执行的函数或代码块完成。当一个协程的代码执行完毕时,它会结束。如果该协程有返回值,通常会将结果传递到一个通道(chan)中,供其他协程或主程序使用。

5. 垃圾回收阶段

协程结束后,如果没有其他引用指向该协程的相关资源,Go 的垃圾回收机制(GC)将会清理掉协程使用的内存和资源。这意味着如果协程持有某些资源(如文件句柄、网络连接等),需要手动关闭或释放这些资源,通常可以通过 defer 来确保。

6. 等待协程结束

在主程序或其他协程中,我们可以通过 sync.WaitGroup 来等待协程完成。例如:

var wg sync.WaitGroupfor i := 0; i < 5; i++ {wg.Add(1) // 增加一个等待任务go func(i int) {defer wg.Done() // 完成时调用 Donefmt.Println(i)}(i)
}wg.Wait() // 等待所有协程完成

协程的生命周期总结

  1. 创建:使用 go 关键字启动协程。
  2. 运行:协程被调度器分配线程执行代码。
  3. 阻塞:协程在等待某些操作时可能进入阻塞状态。
  4. 结束:协程执行完毕,生命周期结束。
  5. 垃圾回收:协程结束后,相关资源被清理。

Go 语言的协程非常轻量级,可以同时运行成千上万的协程,这是 Go 在处理并发任务时的一个优势。


http://www.ppmy.cn/embedded/153984.html

相关文章

《零基础Go语言算法实战》【题目 2-18】获取结构体中字段的 tag 值

《零基础Go语言算法实战》 【题目 2-18】获取结构体中字段的 tag 值 在 Go 语言中&#xff0c;使用 json 包时&#xff0c;在结构体中的字段前会加上 tag&#xff0c;有没有什么办法可以获 取到这个 tag 的内容呢&#xff1f;举例说明。 【解答】 tag 信息可以通过 reflec…

MySQL 与 Redis 的数据一致性问题

读数据的逻辑基本一致问题1: 一致性有哪些?MySQL 与 Redis 的数据一致性方案有哪些?先写MySQL还是先写Redis?缓存数据是更新还是清除?强一致还是最终一致?问题: 如果mysql写成功了,但是Redis写(删除)失败了怎么办?重试机制的幂等问题如何解决? 方案1: 先更新 MySQL 再清…

2025年01月11日Github流行趋势

项目名称&#xff1a;xiaozhi-esp32 项目地址url&#xff1a;https://github.com/78/xiaozhi-esp32项目语言&#xff1a;C历史star数&#xff1a;2433今日star数&#xff1a;321项目维护者&#xff1a;78, MakerM0, whble, nooodles2023, Kevincoooool项目简介&#xff1a;构建…

Leetcode - 147双周赛

目录 一、3407. 子字符串匹配模式二、3408. 设计任务管理器三、3409. 最长相邻绝对差递减子序列四、3410. 删除所有值为某个元素后的最大子数组和 一、3407. 子字符串匹配模式 题目链接 字符串匹配问题&#xff0c;把字符串 p 分成两段 、&#xff0c;i 是 ’ * ’ 的下标&am…

React 进阶之路:深入详解事件绑定的多样方式与区别,促使更加容易理解

React 中的事件绑定是处理用户交互的一个重要方面。React 的事件系统与传统的 DOM 事件系统有所不同&#xff0c;它在设计时考虑了性能、可维护性和易用性&#xff0c;因此 React 提供了多种方式来绑定事件处理程序。理解这些绑定方式及其区别&#xff0c;有助于在实际项目中做…

open3d+opencv实现矩形框裁剪点云操作(C++)

&#x1f451;主页&#xff1a;吾名招财 &#x1f453;简介&#xff1a;工科学硕&#xff0c;研究方向机器视觉&#xff0c;爱好较广泛… ​&#x1f4ab;签名&#xff1a;面朝大海&#xff0c;春暖花开&#xff01; open3dopencv实现矩形框裁剪点云操作&#xff08;C&#xff…

第三章、python中的对象、变量及地址的概念(3.1-3.4)------对象、变量、内存地址及可迭代对象

目录 3.1内存地址(或逻辑地址)、id()、is、in 3.2创建对象及对象的划分问题 3.3变量 3.3.1变量被赋值(=) 3.3.2变量无需声明数据类型 3.3.3变量的作用域(scope)及种类 3.4可迭代对象(Iterable) 第三章、python中的对象、变量及地址的概念 本章讲述编程中对象、变量、地址的基本…

JavaScript Chrome 中的运行

我们在 Chrome 浏览器中可以通过按下 F12 按钮或者右击页面&#xff0c;选择"检查"来开启开发者工具。 也可以在右上角菜单栏选择 "更多工具"》"开发者工具" 来开启&#xff1a; 1、Console 窗口调试 JavaScript 代码 清空 Console 窗口到内容可…