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

【并发模式】Go 常见并发模式实现Runner、Pool、Work

通过并发编程在 Go 程序中实现的3种常见的并发模式。

参考:https://cloud.tencent.com/developer/article/1720733

1、Runner 定时任务

Runner 模式有代表性,能把(任务队列,超时,系统中断信号)等结合起来形成一项定时任务。任何一个条件满足触发,程序就结束了。

import (
 "errors"
 "os"
 "os/signal"
 "time"
)

//Runner 在给定的超时时间内执行一组任务
// 并且在操作系统发送中断信号时结束这些任务
type Runner struct {
 //从操作系统发送信号
 interrupt chan os.Signal
 //报告处理任务已完成
 complete chan error
 //报告处理任务已经超时
 timeout <-chan time.Time
 //持有一组以索引为顺序的依次执行的以 int 类型 id 为参数的函数
 tasks []func(id int)
}

//New 函数返回一个新的准备使用的 Runner,d:自定义分配的时间
func New(d time.Duration) *Runner {
 return &Runner{
  interrupt: make(chan os.Signal, 1),
  complete:  make(chan error),
  //会在另一线程经过时间段 d 后向返回值发送当时的时间。
  timeout: time.After(d),
 }
}

//Add 将一个任务加入到 Runner 中
func (r *Runner) Add(tasks ...func(id int)) {

}

//Start 开始执行所有任务,并监控通道事件
func (r *Runner) Start() error {

}

//执行每一个已注册的任务
func (r *Runner) run() error {
}

//检测是否收到了中断信号
func (r *Runner) gotInterrupt() bool {

}

Runner 类型声明了 3 个通道,用来辅助管理程序的生命周期,以及用来表示顺序执行的不同任务的函数切片。

2、Pool 缓存池

Go 1.6 及之后的版本中,标准库里自带有资源池的实现:sync.Pool,(还有更好的gopool,后者能控制协程数。)

sync.Pool: New、Get、Put

//
func main() {
	// 创建一个 sync.Pool
	var pool sync.Pool

	// 设置对象池的 New 函数,创建对象
	pool.New = func() interface{} {
		return "New Object"
	}

	// 获取对象
	obj := pool.Get()
	fmt.Println(obj) // 输出:New Object

	// 将对象放回池中
	pool.Put("Reused Object")

	// 再次获取对象
	obj = pool.Get()
	fmt.Println(obj) // 输出:Reused Object
}

func main() {
	var studentPool = sync.Pool{
        New: func() interface{} { 
            return new(Student) // 例如创建 Student 对象
        },
    }
    
    //取得对象和归还对象
    stu := studentPool.Get().(*Student)
    json.Unmarshal(buf, stu) // 使用线程池的对象
    studentPool.Put(stu)
    
    //Get() 用于从对象池中获取对象,因为返回值是 interface{},因此需要类型转换。Put() 则是在对象使用完毕后,返回对象池。
 }   

gopool : NewPool、CtxGo

高性能:针对高并发进行了优化,性能较 sync.Pool 更高。
灵活性强:支持更多的池管理选项,比如对象的最大数量、超时时间等。

pool := gopool.NewPool("article_spider", 10, gopool.NewConfig())
//for {}
pool.CtxGo(ctx, func() {
				defer wg.Done()

				c.dbMutex.Lock()
				defer c.dbMutex.Unlock()

				//处理程序
			})

选择指南:

只需要基本的对象池,并且你的性能需求不是特别高,可以选择 sync.Pool。它来自Go 标准库,易用,适合缓存临时对象,减少内存分配带来的开销。

在高并发、低延迟的场景下,或者需要更精细的池管理控制,可以选择 gopool。它为高并发场景进行了优化,提供了更多配置选项,适合需要复杂池管理的应用。

3、work

有缓冲通道


http://www.kler.cn/a/402331.html

相关文章:

  • 海外媒体软文发稿:打开全球传播的新窗口-大舍传媒
  • Android CCodec Codec2 (二一)InputBuffers
  • 【工控】线扫相机小结 第三篇
  • 项目进度计划表:详细的甘特图的制作步骤
  • Vulnhub靶场案例渗透[11]- Momentum2
  • Linux进阶:压缩、解压
  • 开源控件:Qt/C++自定义异形窗口和颜色选择器 【工程源码联系博主索要】
  • 【游戏开发】【Unity】基本的Unity概念
  • 深入解析 MySQL 数据库:负载均衡
  • unity 打包WebGL打开后Input无法输入中文,在手机端无法调用输入法(使用WebGLInput)
  • 【Keil5教程及技巧】耗时一周精心整理万字全网最全Keil5(MDK-ARM)功能详细介绍【建议收藏-细细品尝】
  • SSHPASS或者rsync远程自动连接服务器并且在docker中跑脚本
  • 【迅为】瑞芯微-RK3568开发板Linux+HAL启动测试
  • CSS回顾-CSS选择器详解
  • 智能电视/盒子的应用管理——通过ADB工具优化体验
  • GIS开发该怎么系统性地学习?
  • Unity类银河战士恶魔城学习总结(P132 Merge skill tree with skill Manager 把技能树和冲刺技能相组合)
  • LLM文档对话 —— pdf解析关键问题
  • 在 WSL2 Ubuntu22.04环境安装 MySQL
  • k8s -20241119