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

golang学习笔记05——golang协程池,怎么实现协程池?

  • 推荐学习文档
    • golang应用级os框架,欢迎star
    • golang实战大纲
    • golang优秀开发常用开源库汇总
    • golang学习笔记01——基本数据类型
    • golang学习笔记02——gin框架及基本原理
    • golang学习笔记03——gin框架的核心数据结构
    • golang学习笔记04——如何真正写好Golang代码?

在这里插入图片描述

协程池是一种用于高效处理任务的机制,通过池中协程(称为 “工作者”)来并发执行任务。通过调整协程数量、使用缓冲通道、关闭协程池并监控其指标,可以优化协程池。协程池在实践中可用于处理大量并发任务、图像处理任务等,通过将任务提交给协程池,可以提高处理并发的效率。

GoLang 协程池的管理与优化

协程池概述

协程池是一种用于管理协程组的机制,它可以帮助避免创建和销毁协程的开销。协程池中的协程被称为 “工作者”,它们处理传入的任务。

协程池的好处

  • 减少协程创建的开销。
  • 提高任务处理并发度。
  • 允许任务在独立的上下文环境中执行。

协程池实现

在 GoLang 中,可以创建一个协程池来实现并发任务处理:

package main

import (
    "fmt"
    "sync"
    "time"
)

type Job struct {
    Data    int
    Result  chan int
}

func main() {
    // 创建一个有缓冲的通道用于处理任务结果
    result := make(chan int, 10)

    // 创建一个协程池
    var wg sync.WaitGroup
    pool := make(chan *Job)
    for i := 0; i < 4; i++ {
        wg.Add(1)
        go func(pool chan *Job, wg *sync.WaitGroup) {
            defer wg.Done()
            for {
                job := <-pool
                job.Result <- job.Data * job.Data
            }
        }(pool, &wg)
    }

    // 模拟任务处理
    for i := 0; i < 10; i++ {
        job := Job{
            Data:   i,
            Result: result,
        }
        pool <- &job
    }
    close(pool)

    wg.Wait()
    close(result)

    // 打印任务结果
    for r := range result {
        fmt.Println(r)
    }
}

优化协程池

以下是一些优化协程池的技巧:

  • 调整协程数量:协程数量应与系统资源和任务负载相匹配。过多或过少的协程都会影响性能。
  • 使用缓冲通道:在向协程池发送任务时,使用缓冲通道可以防止协程阻塞。
  • 关闭协程池:在不再需要协程池时,应使用 close() 函数关闭它,释放所有协程。
  • 监控协程池:使用诸如 Prometheus 之类的工具监控协程池的指标,例如协程数量和任务处理时间。

实战案例

在以下实战案例中,协程池用于处理图像处理任务:

package main

import (
    "fmt"
    "sync"
    "time"

    "image"
    "image/jpeg"
    "os"
)

type Job struct {
    ImageFile    string
    ResultImage  chan<- image.Image
}

func main() {
    resultChan := make(chan image.Image)

    // 创建一个协程池
    var wg sync.WaitGroup
    pool := make(chan *Job)
    for i := 0; i < 4; i++ {
        wg.Add(1)
        go func(pool chan *Job, wg *sync.WaitGroup) {
            defer wg.Done()
            for {
                job := <-pool
                image, err := loadAndProcessImage(job.ImageFile)
                if err != nil {
                    fmt.Println(err)
                    continue
                }
                job.ResultImage <- image
            }
        }(pool, &wg)
    }

    // 将图像处理任务提交给协程池
    for {
        imageFile, ok := <-filesChan  // 从文件通道取文件
        if !ok {
            break
        }
        job := Job{
            ImageFile:   imageFile,
            ResultImage: resultChan,
        }
        pool <- &job
    }
    close(pool)

    wg.Wait()
    close(resultChan)

    // 保存处理后的图像
    for img := range resultChan {
        outputFile, err := os.Create("p_" + imgFile)
        if err != nil {
            fmt.Println(err)
            continue
        }
        if err := jpeg.Encode(outputFile, img, &jpeg.Options{Quality: 95}); err != nil {
            fmt.Println(err)
            outputFile.Close()
            continue
        }
        outputFile.Close()
    }
}

以上就是Golang协程池的实现详细内容,关注我看更多有意思的文章哦!👉👉


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

相关文章:

  • springboot+vue+mybatis计算机毕业设计气象数据分析与可视化系统+PPT+论文+讲解+售后
  • RuoYi 开源框架,集成了后端管理,后端java版 App 移动解决方案
  • C#程序 Debugger,Release都没问题,但是,打包安装后:System.FormatException: 输入字符串的格式不正确
  • 【VUE】11、安装nvm管理多个版本的node.js
  • 【学习笔记-opencv yolov8】
  • Redis——初识Redis
  • OpenAI即将推出推理AI大模型“草莓”
  • 离散时域和连续频谱之间的傅里叶
  • 【1】compose中获取窗口尺寸,宽度高度
  • springboot系列--自动配置原理
  • 产品经理的发现和成长
  • 基于Prometheus和Grafana构建现代服务器监控体系的解决方案
  • 使用Python通过字节串或字节数组加载和保存PDF文档
  • GAN及其变体
  • docker Get https://registry-1.docker.io/v2/: x509: certificate is valid for
  • 使用Python实现多个PDF文件的合并
  • 鸿蒙开发(API 12 Beta6版)【P2P模式】 网络WLAN服务开发
  • 教学辅助微信小程序|基于SSM+vue的高校教学微信小程序系统(源码+数据库+文档)
  • Android 源码中jni项目 加载so目录小结
  • 81页PPT产业园5G多功能智慧灯杆整体规划设计方案