当前位置: 首页 > 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)

}

相关文章:

  • 汽车IVI中控开发入门及进阶(二十七):车载摄像头vehicle camera
  • 区块链2024
  • 技术干货|如何快速提升SNMP监控性能
  • 揭秘古代手术工具与技术:从中国起源的医疗奇迹
  • 板凳------56.Linux/Unix 系统编程手册(下) -- SOCKET 介绍
  • [C#] opencvsharp对Mat数据进行序列化或者反序列化以及格式化输出
  • Linux常用命令(17)—pastesortcomm命令(有相关截图)
  • ES6(ECMAScript 6.0) 新特性
  • 如何将 ChatGPT 集成到你的应用中
  • mysql数据库中给表创建数据
  • 靠3个字寻求机会,情商不够,别勉强自己
  • Aquila-Med LLM:开创性的全流程开源医疗语言模型
  • .NET C# 装箱与拆箱
  • TPS、QPS、CPS、PV和UV
  • 深入理解前端缓存
  • LeetCode 1-两数之和
  • 主干网络篇 | YOLOv5/v7 更换主干网络之 ResNet50/ResNet101 | 对比实验必备
  • RIP路由协议汇总、版本兼容、定时器、协议优先级配置(华为)
  • hive拉链表详解
  • 制作WIFI二维码,实现一键扫描连接WIFI
  • 屈晓华履新四川省社科联党组书记,此前担任省国动办主任
  • 图忆|红场阅兵:俄罗斯30年来的卫国战争胜利日阅兵式
  • 最新研究:基因编辑治疗晚期胃肠道癌显成效
  • 正荣地产:公司控股股东已获委任联合清盘人
  • 金沙记忆|元谋龙街渡:是起点也是终点
  • 48岁黄世芳履新中国驻毛里求斯大使,曾在广西工作多年