利用go語言編寫一個并發(fā)包
寫在前面
這是一個只需要用50行代碼(核心代碼只有15行)實現(xiàn)的極其簡單(原理簡單、使用方法簡單、功能簡單)的go包mini_parallel_job,適合大部分并發(fā)任務,開箱即用。
代碼
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() { // 串行執(zhí)行 begin1 := time.Now() for i := 0; i < JobCount; i++ { fib(40) } fmt.Println(time.Since(begin1)) // 并行執(zhí)行 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)) /* 結(jié)果: 7.335989407s 1.112108503s */ } // 任務 func fib(n int) int { if n == 0 || n == 1 { return n } return fib(n-2) + fib(n-1) }
總結(jié)
這段代碼僅僅實現(xiàn)使用go rountine
實現(xiàn)并發(fā),sync.WaitGroup
實現(xiàn)等待。
在大多數(shù)場景中,只需要并發(fā),并不關心并發(fā)量是多少,大多數(shù)程序員也是使用Wait
函數(shù)那段代碼實現(xiàn)的(至少作者在項目中看到都是這樣的,并且有多處相同的代碼,基于此場景封裝了一下)。
如果要實現(xiàn)復雜一點的場景,比如控制最大并發(fā)量,可以稍微對上述代碼做一些修改,Wait
函數(shù)中加一個指定大小的chan
來控制?;蛘邊⒖甲髡吡硗庖粋€對go并發(fā)的封裝gopool,使用master-worker模式實現(xiàn)的并發(fā)控制。
到此這篇關于利用go語言編寫一個并發(fā)包的文章就介紹到這了,更多相關go并發(fā)包內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
使用Go?goroutine實現(xiàn)并發(fā)的Clock服務
這篇文章主要為大家詳細介紹了如何使用Go?goroutine實現(xiàn)并發(fā)的Clock服務,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2023-06-06如何使用go實現(xiàn)創(chuàng)建WebSocket服務器
文章介紹了如何使用Go語言和gorilla/websocket庫創(chuàng)建一個簡單的WebSocket服務器,并實現(xiàn)商品信息的實時廣播,感興趣的朋友一起看看吧2024-11-11gin通過go build -tags實現(xiàn)json包切換及庫分析
這篇文章主要為大家介紹了gin通過go build -tags實現(xiàn)json包切換及庫分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09