利用go语言编写一个并发包

 更新时间:2023年10月22日 08:08:26   作者:nil  
这篇文章主要为大家详细介绍了如何利用go语言编写一个并发包,适合大部分并发任务,开箱即用,文中的示例代码讲解详细,有需要的小伙伴可以参考下

写在前面

这是一个只需要用50行代码(核心代码只有15行)实现的极其简单(原理简单、使用方法简单、功能简单)的go包mini_parallel_job,适合大部分并发任务,开箱即用。

代码

package mini_parallel_job

import (
    "fmt"
    "sync"
)

type JobType func()

type JobPool interface {
    AddJob(jobType JobType)
    Wait()
}

type jobPool struct {
    jobs []JobType
}

// 添加任务
func (j *jobPool) AddJob(job JobType) {
    j.jobs = append(j.jobs, job)
}

// 开始并且等待任务
func (j *jobPool) Wait() {
    var wg sync.WaitGroup
    wg.Add(len(j.jobs))
    for i := range j.jobs {
       jJob := j.jobs[i]
       go func() {
          defer func() {
             wg.Done()
             if err := recover(); err != nil {
                fmt.Printf("err:%+v", err)
             }
          }()

          jJob()
       }()
    }
    wg.Wait()
}

func NewJobPool() JobPool {
    return &jobPool{
       jobs: make([]JobType, 0),
    }
}

压测

package mini_parallel_job

import (
    "testing"
)

const (
    Count = 10
)

// 并行任务
func parallelJob() {
    jobPool := NewJobPool()
    for i := 0; i < Count; i++ {
       jobPool.AddJob(func() {
          _ = fib(10)
       })
    }
    jobPool.Wait()
}

// 串行任务
func serialJob() {
    for i := 0; i < Count; i++ {
       _ = fib(10)
    }
}

// 任务
func fib(n int) int {
    if n == 0 || n == 1 {
       return n
    }
    return fib(n-2) + fib(n-1)
}

// 性能测试
func BenchmarkSerialJob(b *testing.B) {
    for i := 0; i < b.N; i++ {
       serialJob()
    }
}

func BenchmarkParallelJob(b *testing.B) {
    for i := 0; i < b.N; i++ {
       parallelJob()
    }
}

/*
BenchmarkSerialJob-12             298855              3756 ns/op
BenchmarkParallelJob-12           117189              8710 ns/op
*/

example

package main

import (
    "fmt"
    mini_parallel_job "mini-parallel-job"
    "time"
)

const (
    JobCount = 10
)

func main() {
    // 串行执行
    begin1 := time.Now()
    for i := 0; i < JobCount; i++ {
       fib(40)
    }
    fmt.Println(time.Since(begin1))

    // 并行执行
    begin2 := time.Now()
    parallelJob := mini_parallel_job.NewJobPool()
    for i := 0; i < JobCount; i++ {
       parallelJob.AddJob(func() {
          fib(40)
       })
    }
    parallelJob.Wait()
    fmt.Println(time.Since(begin2))

    /*
       结果:
       7.335989407s
       1.112108503s
    */
}

// 任务
func fib(n int) int {
    if n == 0 || n == 1 {
       return n
    }
    return fib(n-2) + fib(n-1)
}

总结

这段代码仅仅实现使用go rountine实现并发,sync.WaitGroup实现等待。

在大多数场景中,只需要并发,并不关心并发量是多少,大多数程序员也是使用Wait函数那段代码实现的(至少作者在项目中看到都是这样的,并且有多处相同的代码,基于此场景封装了一下)。

如果要实现复杂一点的场景,比如控制最大并发量,可以稍微对上述代码做一些修改,Wait函数中加一个指定大小的chan来控制。或者参考作者另外一个对go并发的封装gopool,使用master-worker模式实现的并发控制。

到此这篇关于利用go语言编写一个并发包的文章就介绍到这了,更多相关go并发包内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用Go goroutine实现并发的Clock服务

    使用Go goroutine实现并发的Clock服务

    这篇文章主要为大家详细介绍了如何使用Go goroutine实现并发的Clock服务,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-06-06
  • 谈谈对Golang IO读写的困惑

    谈谈对Golang IO读写的困惑

    这篇文章主要介绍了谈谈对Golang IO读写的困惑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • goLand Delve版本太老的问题及解决

    goLand Delve版本太老的问题及解决

    这篇文章主要介绍了goLand Delve版本太老的问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • 如何使用go实现创建WebSocket服务器

    如何使用go实现创建WebSocket服务器

    文章介绍了如何使用Go语言和gorilla/websocket库创建一个简单的WebSocket服务器,并实现商品信息的实时广播,感兴趣的朋友一起看看吧
    2024-11-11
  • Go使用缓存加速外部资源访问提高性能效率

    Go使用缓存加速外部资源访问提高性能效率

    缓存是架构设计中的常用概念,本文基于Go实现了一个简单的缓存组件,支持最基本的缓存操作,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • Go语言文件读写操作案例详解

    Go语言文件读写操作案例详解

    这篇文章主要为大家介绍了Go语言文件读写操作案例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • GO语言常用的文件读取方式

    GO语言常用的文件读取方式

    这篇文章主要介绍了GO语言常用的文件读取方式,涉及一次性读取、分块读取与逐行读取等方法,是非常实用的技巧,需要的朋友可以参考下
    2014-12-12
  • GoLang BoltDB数据库详解

    GoLang BoltDB数据库详解

    这篇文章主要介绍了GoLang BoltDB数据库,boltdb是使用Go语言编写的开源的键值对数据库,boltdb存储数据时 key和value都要求是字节数据,此处需要使用到 序列化和反序列化
    2023-02-02
  • gin通过go build -tags实现json包切换及库分析

    gin通过go build -tags实现json包切换及库分析

    这篇文章主要为大家介绍了gin通过go build -tags实现json包切换及库分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • go语言中fallthrough的用法说明

    go语言中fallthrough的用法说明

    这篇文章主要介绍了go语言中fallthrough的用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05

最新评论