golang的context和chan 的使用

1. context 作用

context包的context的接口,主要是控制协程执行上下文的时间,以及取消程序的执行,以及上下文中传递数据等作用,golang中耗时或者需要协同的操作都会见到context的身影。

context有几个常用的方法

1.1 context.Backgroud()

创建一个空白的,顶级的,不会被取消的上下文。

1.2 context.WithTimeout

创建一个有执行时间限制的上下文

func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {

return WithDeadline(parent, time.Now().Add(timeout))

}

可以通过ctx.Done()方法获取上下超时的通知。

go 复制代码
package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	parentCxt := context.Background()
	ctx, cancel := context.WithTimeout(parentCxt, time.Second*5)

	go longTimeTask(ctx)

	time.Sleep(time.Second * 10)
	cancel()
	fmt.Println("task cancel success")
}

func longTimeTask(ctx context.Context) {
	for {
		//fmt.Println("ok")
		select {
		case <-time.After(time.Second * 1):
			fmt.Println("task compete")
		case <-ctx.Done():
			fmt.Println("time out")
			return
		}
	}
}

1.3 context.WitchCancel(parentContext)

获取一个可以中止的上下文,该方法会返回一个新的context,和cancel函数,调用cancel函数后,通过ctx.Done()方法可以获取到上下文取消的通知

go 复制代码
package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	parentCxt := context.Background()
	ctx, cancel := context.WithCancel(parentCxt)

	go longTimeTask(ctx)

	time.Sleep(time.Second * 10)
	cancel()
	fmt.Println("task cancel success")
}

func longTimeTask(ctx context.Context) {
	for {
		//fmt.Println("ok")
		select {
		case <-time.After(time.Second * 1):
			fmt.Println("task compete")
		case <-ctx.Done():
			fmt.Println("time out")
			return
		}
	}
}

1.4 context.WithValue()

func WithValue(parent Context, key, val any) Context {

if parent == nil {

panic("cannot create context from nil parent")

}

if key == nil {

panic("nil key")

}

if !reflectlite.TypeOf(key).Comparable() {

panic("key is not comparable")

}

return &valueCtx{parent, key, val}

}

可以在上下文中存贮一些参数,通过上下文随时获取。

2.chan 信道

golang的chan和map,切片,接口,函数一样是引用类型。

golang更加推荐使用chan去解决并发的协作的问题,对chan的读写是并发安全的,当然你也可也以使用sync.Mutex等包来控制并发。

相关推荐
chouchuang8 分钟前
day-030-综合练习-笔记管理器
开发语言·笔记·python
Reart18 分钟前
Leetcode 213.打家劫舍2(内含闲谈,打劫真是技术活,好题,716)
后端·算法
触底反弹34 分钟前
🔥 RAG 到底是怎么工作的?掰开揉碎了给你讲明白!
javascript·人工智能·后端
云空1 小时前
《Three.js 3D实例大全》
开发语言·javascript·3d·three.js
techdashen1 小时前
Go 1.26 新增 `bytes.Buffer.Peek`:只看数据,不移动读取位置
开发语言·后端·golang
Reart1 小时前
Leetcode 198.打家劫舍(716)
后端·算法
C137的本贾尼2 小时前
第七篇:消息队列(MQ)——就是个带存储的异步通信管道
java·开发语言·中间件
Java编程爱好者2 小时前
Spring6.0+Boot3.0:秒级启动、万级并发的开发新姿势
后端
YYYing.2 小时前
【C++大型项目之高性能服务器框架 (七) 】Socket与ByteArray模块
服务器·c++·后端·框架·高性能·c/c++
青山木2 小时前
一把 Redis 分布式锁,踩透四个坑:锁争抢、僵尸锁、锁过期、锁丢失
java·数据库·redis·后端