golang并发控制

常见的并发控制
常见的并发控制

channel:通过无缓冲的channel进行同步调用,有缓冲的channel进行异步调用,也可限制并发数量

waitgroup:可以通过add来动态调整,释放的时间需要使用defer 进行wg.done操作

context:通过在协程之间传递上下文消息,可对派生的子协程进行并发控制,防止资源浪费

高并发任务控制包

b站开源的并发控制包,对以上三种并发控制包的优点进行融合。限制并发数量,对并发上下文控制等。 虽然官方在go1.17版本也引入并发控制包,但没有b站开源的支持场景多,建议使用b站开源包,简单场景可使用官方包。我们一般使用高并发,处理大量的数据分析工作。对用一个job拥有子任务的时候,对于整个任务有两种限制:

  • 一个任务失败会导致所有*未进行或进行中*的任务被 cancel
  • 一个任务失败导致所有任务被 cancel

Notice:在并行进行任务调度的时候,做好业务侧兜底,失败的任务进行日志记录,告警等。

并发控制包

kratos并发控制包:

errgroup package - github.com/bilibili/kratos/pkg/sync/errgroup - Go Packages

官方1.17后引入:

https://pkg.go.dev/golang.org/x/sync/errgroup#pkg-overview

b站开源开发控制包demo详情

并发数量限制

设置最大并行数 GOMAXPROCS 对以上三种使用方式均起效 NOTE: 由于 errgroup 实现问题,设定 GOMAXPROCS 的 errgroup 需要立即调用 Wait() 例如:

复制代码
g := errgroup.WithCancel(ctx)
g.GOMAXPROCS(2)
// task1
g.Go(func(ctx context.Context) {
    fmt.Println("task1")
})
// task2
g.Go(func(ctx context.Context) {
    fmt.Println("task2")
})
// task3
g.Go(func(ctx context.Context) {
    fmt.Println("task3")
})
// NOTE: 此时设置的 GOMAXPROCS 为2, 添加了三个任务 task1, task2, task3 此时 task3 是不会运行的!
// 只有调用了 Wait task3 才有运行的机会
g.Wait() // task3 运行

子任务失败所有任务被取消

复制代码
g := errgroup.WithCancel(ctx)
g.Go(func(ctx context.Context) {
    // NOTE: 此时 ctx 是从 errgroup.WithContext 传递的 ctx 派生出的 ctx
    // do something
})

子任务执行失败不影响其他子任务继续执行

复制代码
直接使用 此时不会因为一个任务失败导致所有任务被 cancel:

g := &errgroup.Group{}
g.Go(func(ctx context.Context) {
	// NOTE: 此时 ctx 为 context.Background()
	// do something
})
WithContext 使用 WithContext 时不会因为一个任务失败导致所有任务被 cancel:

g := errgroup.WithContext(ctx)
g.Go(func(ctx context.Context) {
	// NOTE: 此时 ctx 为 errgroup.WithContext 传递的 ctx
	// do something
})

参考资料:

errgroup package - github.com/bilibili/kratos/pkg/sync/errgroup - Go Packages

errgroup package - golang.org/x/sync/errgroup - Go Packages

相关推荐
Livingbody1 分钟前
通过huggingface学习【自动语音识别(Automatic Speech Recognition, ASR)】
后端
YGGP2 分钟前
吃透 Golang 基础:数据结构之 Map
开发语言·数据结构·golang
~plus~4 分钟前
Harmony核心:动态方法修补与.NET游戏Mod开发
开发语言·jvm·经验分享·后端·程序人生·c#
步、步、为营11 分钟前
.NET 事件模式举例介绍
java·开发语言·.net
~plus~14 分钟前
WPF八大法则:告别模态窗口卡顿
开发语言·经验分享·后端·程序人生·c#
Livingbody19 分钟前
Transformers Pipeline 入门之【任务列表】
后端
march of Time24 分钟前
go工具库:hertz api框架 hertz client的使用
开发语言·golang·iphone
[email protected]26 分钟前
ASP.NET Core SignalR - 部分客户端消息发送
后端·asp.net·.netcore
寻月隐君26 分钟前
深入解析 Rust 的面向对象编程:特性、实现与设计模式
后端·rust·github
追逐时光者30 分钟前
免费且全面的C#/.NET/.NET Core面试宝典,阅读量突破40万+了!
后端·.net