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

go的context总结

Go语言中的context包提供了一种在不同Goroutines之间传递取消信号、超时、截止日期和请求范围值的方法,用于更好地管理并控制并发操作。

WithCancel

在这个示例中,我们首先创建了一个带有取消功能的context,然后启动了一个Goroutine来执行某项工作,这个Goroutine在工作过程中定期检查ctx.Done()通道,如果接收到取消信号,则停止工作。在main函数中,我们等待了一段时间,然后调用cancel函数,以发送取消信号。在取消信号发送后,Goroutine会收到信号并停止工作。

package main

import (

    "context"

    "fmt"

    "time"

)

func doSomething(ctx context.Context) {

    for {

        select {

        case <-ctx.Done():

            fmt.Println("Received cancellation signal. Cleaning up...")

            return

        default:

            // Simulate some work

            fmt.Println("Working...")

            time.Sleep(1 * time.Second)

        }

    }

}

func main() {

    // 创建一个带有取消功能的context

    ctx, cancel := context.WithCancel(context.Background())

    // 启动一个Goroutine执行某项工作,传入context

    go doSomething(ctx)

    // 等待一段时间,然后取消工作

    time.Sleep(10 * time.Second)

    cancel() // 调用cancel函数来发送取消信号

    // 等待一段时间,以观察工作是否被取消

    time.Sleep(5 * time.Second)

}

WithTimeout

在这个示例中,我们首先创建一个带有超时控制的 context,并设置最大执行时间为 5 秒。然后,我们启动一个 Goroutine 来执行某项工作。主函数休眠 10 秒以等待 Goroutine 的完成或超时。由于 context.WithTimeout 设置了最大执行时间为 5 秒,因此 Goroutine 会在 5 秒后收到超时信号,结束工作。

context.WithTimeout 可以用于控制并发操作的执行时间,以确保它们不会无限期地运行。这在处理网络请求、I/O 操作、调用外部服务等场景中特别有用,以避免操作长时间阻塞并占用资源。

package main

import (

    "context"

    "fmt"

    "time"

)

func doSomething(ctx context.Context) {

    for {

        select {

        case <-ctx.Done():

            fmt.Println("Received cancellation signal. Cleaning up...")

            return

        case <-time.After(1 * time.Second):

            fmt.Println("Task completed.")

        }

    }

}

func main() {

    // 创建一个带有超时控制的 context,设置最大执行时间为 5 秒

    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)

    defer cancel() // 一定要记得调用 cancel,确保资源得以释放

    // 启动一个 Goroutine 执行某项工作,传入 context

    go doSomething(ctx)

    // 主函数休眠 10 秒,以等待 Goroutine 完成或超时

    time.Sleep(10 * time.Second)

}

WithValue

package main

import (

    "context"

    "fmt"

    "time"

)

func processRequest(ctx context.Context) {

    // 从context中获取请求ID

    requestID, ok := ctx.Value("requestKey").(int)

    if !ok {

        fmt.Println("Request ID not found in context.")

        return

    }

    fmt.Printf("Processing request with ID %d\n", requestID)

}

func main() {

    // 创建一个带有请求ID的context

    ctx := context.WithValue(context.Background(), "requestKey", 12345)

    // 在另一个函数中使用context

    go processRequest(ctx)

    // 主函数休眠一段时间,以确保Goroutine有时间运行

    time.Sleep(5 * time.Second)

}

WithDeadline

context.WithDeadline 方法用于创建一个带有截止日期的 context,允许你设置一个操作的最后截止日期,如果操作在截止日期之后仍未完成,context 会自动取消它。

package main

import (

    "context"

    "fmt"

    "time"

)

func doSomething(ctx context.Context) {

    for {

        select {

        case <-ctx.Done():

            fmt.Println("Received cancellation signal. Cleaning up...")

            return

        case <-time.After(1 * time.Second):

            fmt.Println("Task completed.")

        }

    }

}

func main() {

    // 设置截止日期为当前时间加 5 秒

    deadline := time.Now().Add(5 * time.Second)

    // 创建一个带有截止日期的 context

    ctx, cancel := context.WithDeadline(context.Background(), deadline)

    defer cancel() // 一定要记得调用 cancel,确保资源得以释放

    // 启动一个 Goroutine 执行某项工作,传入 context

    go doSomething(ctx)

    // 主函数休眠 10 秒,以等待 Goroutine 完成或截止日期到达

    time.Sleep(10 * time.Second)

}

context继承

这个例子5秒后结束程序。

package main

import (

    "context"

    "fmt"

    "time"

)

func doSomething(ctx context.Context) {

    for {

        select {

        case <-ctx.Done():

            fmt.Println("Received cancellation signal. Cleaning up...")

            return

        default:

            // Simulate some work

            fmt.Println("Working...")

            time.Sleep(1 * time.Second)

        }

    }

}

func main() {

    // 创建一个带有取消功能的context

    rootCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)

    ctx, cancel := context.WithCancel(rootCtx)

    // 启动一个Goroutine执行某项工作,传入context

    go doSomething(ctx)

    // 等待一段时间,然后取消工作

    time.Sleep(10 * time.Second)

    cancel() // 调用cancel函数来发送取消信号

    // 等待一段时间,以观察工作是否被取消

    time.Sleep(5 * time.Second)

}

相关文章:

  • 开源项目壮大和创新
  • 颍川文明的传承
  • 微信小程序毕业设计-餐厅点餐系统项目开发实战(附源码+论文)
  • 设计模式——设计模式原则
  • [Django学习]查询过滤器(lookup types)
  • SpringSecurity实战入门——授权
  • 【实战】Spring Cloud Stream 3.1+整合Kafka
  • Python学习路线
  • vue3父组件获取子组件的实例对象
  • Ollama部署大模型并安装WebUi
  • 抽象类和接口有什么区别?
  • reidis的内存回收和内存淘汰策略
  • Android C++系列:C++最佳实践2抽象类
  • Spring Boot 增删改查(mybatis-plus)
  • MSPM0G3507——PWM
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • fetch 从初识到应用
  • iOS 系统授权开发
  • JavaScript服务器推送技术之 WebSocket
  • JavaWeb(学习笔记二)
  • k8s 面向应用开发者的基础命令
  • mysql innodb 索引使用指南
  • Redis中的lru算法实现
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • 浮现式设计
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 一份游戏开发学习路线
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • ​VRRP 虚拟路由冗余协议(华为)
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • # 详解 JS 中的事件循环、宏/微任务、Primise对象、定时器函数,以及其在工作中的应用和注意事项
  • #宝哥教你#查看jquery绑定的事件函数
  • $$$$GB2312-80区位编码表$$$$
  • $.ajax()方法详解
  • (2024,RWKV-5/6,RNN,矩阵值注意力状态,数据依赖线性插值,LoRA,多语言分词器)Eagle 和 Finch
  • (31)对象的克隆
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (简单) HDU 2612 Find a way,BFS。
  • (原)本想说脏话,奈何已放下
  • (原創) 物件導向與老子思想 (OO)
  • (转)h264中avc和flv数据的解析
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • ***利用Ms05002溢出找“肉鸡
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • .bat批处理出现中文乱码的情况
  • .NET Framework与.NET Framework SDK有什么不同?
  • .NET 跨平台图形库 SkiaSharp 基础应用
  • .NET设计模式(2):单件模式(Singleton Pattern)
  • .net实现头像缩放截取功能 -----转载自accp教程网
  • .Net中的集合