当前位置: 首页 > news >正文

golang 协程 如何中断和恢复

Go语言通知协程退出(取消)的几种方式 - 知乎

GoLang之goroutine底层系列二(goroutine的创建、让出、恢复)_golang goroutine-CSDN博客

在 Go 语言中,协程(也称为 goroutine)是通过 go 关键字启动的轻量级线程。由于 goroutine 的调度是由 Go 运行时管理的,直接停止一个正在执行的 goroutine 是不可能的,这与操作系统线程不同。但是,你可以通过一些策略来实现“中断”和“恢复”的行为,尽管这不是传统意义上的停止和恢复。

1. 使用通道(Channel)进行信号传递

最常用的方法是使用通道(channel)来安全地中断 goroutine。你可以在另一个 goroutine 中向该 goroutine 发送一个信号(例如,一个特殊的值或者一个结构体),然后在被中断的 goroutine 中定期检查这个通道以决定是否退出循环或函数。

package mainimport ("fmt""time"
)func worker(done chan bool) {for {select {case <-done:fmt.Println("Worker stopped.")return // 退出函数,结束 goroutinedefault:fmt.Println("Working...")time.Sleep(500 * time.Millisecond) // 模拟工作}}
}func main() {done := make(chan bool)go worker(done)time.Sleep(2 * time.Second) // 等待一段时间done <- true               // 发送信号到 worker,要求它停止time.Sleep(1 * time.Second) // 等待 worker 完全停止
}

2. 使用 context 包

context 包是 Go 标准库中处理请求范围的值、取消信号和截止时间的标准方式。它非常适合用来控制 goroutine 的生命周期。

示例代码:

package mainimport ("context""fmt""time"
)func worker(ctx context.Context) {for {select {case <-ctx.Done(): // 当 ctx 被取消时,这里会被触发fmt.Println("Worker stopped.")return // 退出函数,结束 goroutinedefault:fmt.Println("Working...")time.Sleep(500 * time.Millisecond) // 模拟工作}}
}func main() {ctx, cancel := context.WithCancel(context.Background())go worker(ctx)time.Sleep(2 * time.Second) // 等待一段时间cancel()                    // 取消 context,要求 worker 停止time.Sleep(1 * time.Second) // 等待 worker 完全停止
}

3. 使用 sync.Once 或 sync.Mutex 控制退出逻辑的执行一次

如果你需要在某些情况下只安全地执行退出逻辑一次,可以使用 sync.Once 来确保。这对于确保资源清理代码只运行一次非常有用。但是,这种方法更多地是关于如何安全地执行退出逻辑,而不是真正地“中断”一个正在执行的 goroutine。

示例代码:

package mainimport ("fmt""sync""time"
)var once sync.Once
var running = true // 控制循环是否继续运行的标志位func worker() {for running { // 使用 running 作为循环条件来控制何时退出循环体中的代码块。fmt.Println("Working...")time.Sleep(500 * time.Millisecond) // 模拟工作}
}func stopWorker() { // 安全地停止 worker 的函数。使用 sync.Once 确保只调用一次。once.Do(func() { // 使用 sync.Once 来确保这个操作只执行一次。running = false // 设置 running 为 false,让循环在下次迭代时退出。})
}

在上面的代码中,你可以通过调用 stopWorker() 来停止 worker() 函数。但是,这种方法更多地是控制何时退出循环而不是真正地“中断”一个正在执行的 goroutine。在实践中,通常推荐使用通道或 context 来管理 goroutine 的生命周期。

http://www.lryc.cn/news/581594.html

相关文章:

  • React 各颜色转换方法、颜色值换算工具HEX、RGB/RGBA、HSL/HSLA、HSV、CMYK
  • 存储延时数据,帮你选数据库和缓存架构
  • 微前端架构在嵌入式BI中的集成实践与性能优化
  • 20250706-4-Docker 快速入门(上)-常用容器管理命令_笔记
  • Windows 11 Enterprise LTSC 转 IoT
  • 前端防抖Debounce如何实现
  • 小白成长之路-mysql数据基础(三)
  • stm32地址偏移:为什么相邻寄存器的地址偏移量0x04表示4个字节?
  • 【JS逆向基础】数据分析之XPATH
  • android 获取手机配对的蓝牙耳机的电量
  • 【PyTorch】PyTorch中torch.nn模块的池化层
  • 全能视频处理工具介绍说明
  • [shad-PS4] docs | 内核/系统服务 | HLE-高等级模拟
  • Spark流水线数据质量检查组件
  • UNet改进(16):稀疏注意力(Sparse Attention)在UNet中的应用与优化策略
  • Redis集群和 zookeeper 实现分布式锁的优势和劣势
  • 物联网实施与运维【路由器/网关配置】+智能楼道系统
  • python库 dateutil 库的各种案例的使用详解
  • 【Note】《Kafka: The Definitive Guide》第三章: Kafka 生产者深入解析:如何高效写入 Kafka 消息队列
  • Android studio在点击运行按钮时执行过程中输出的compileDebugKotlin 这个任务是由gradle执行的吗
  • 升级AGP(Android Gradle plugin)和gradle的版本可以提高kapt的执行速度吗
  • 【python】对纯二进制向量(仅包含 0 和 1,长度为 8 或 16)的检测和提取
  • 基于腾讯云开发与“人·事·财·物”架构理念的家政预约小程序设计与实现
  • 【Python练习】030. 编写一个函数,实现字符串的反转
  • Python 中 ffmpeg-python 库的详细使用
  • 一条 SQL 语句的内部执行流程详解(MySQL为例)
  • 2025 JuniorCryptCTF re 部分wp
  • 重力翻转者:原创趣味小游戏
  • 前端开发常见问题(从布局到性能优化)
  • 【libm】 10 rem_pio2函数 (rem_pio2.rs)