Golang協(xié)程池的實(shí)現(xiàn)與應(yīng)用
1. 為什么需要協(xié)程池
使用協(xié)程池的好處是減少在創(chuàng)建和銷毀協(xié)程上所花的時(shí)間以及資源的開銷,解決資源不足的問題。如果不使用協(xié)程池,有可能造成系統(tǒng)創(chuàng)建大量同類協(xié)程池而導(dǎo)致消耗完內(nèi)存或者內(nèi)存泄漏的問題。
2. 使用協(xié)程池的優(yōu)點(diǎn)
- 不用手動(dòng)頻繁的創(chuàng)建協(xié)程了
- 方便統(tǒng)一管理,只用管理池子就行了
- 提高響應(yīng)速度,一有任務(wù)如果有剛執(zhí)行完的協(xié)程就能馬上去執(zhí)行新任務(wù)
3. 設(shè)計(jì)思路
Task 任務(wù)對象->EntryChannel->JobsChannel <-Pool(worker)
4. 實(shí)現(xiàn)一個(gè)簡單的協(xié)程池
4.1 Task 任務(wù)對象
type Task struct { // Task方法 任務(wù) method func() error // 可以擴(kuò)展 } // NewTask 創(chuàng)建一個(gè)Task func NewTask(method func() error) *Task { return &Task{ method: method, } } // Execute 任務(wù)執(zhí)行 func (t *Task) Execute() { err := t.method() if err != nil { panic(err) } }
4.2 Pool協(xié)程池
// 定義一個(gè)協(xié)程池 type Pool struct { // 對外的Task入口 EntryChannel chan *Task // 對內(nèi)的Task隊(duì)列 JobsChannel chan *Task // 協(xié)程池的最大work數(shù)量 WorkerNum int } // NewPool 創(chuàng)建Pool的函數(shù) func NewPool(cap int) *Pool{ return &Pool{ EntryChannel: make(chan *Task), JobsChannel: make(chan *Task), WorkerNum: cap, } } // 協(xié)程池創(chuàng)建一個(gè)Worker func (p *Pool)worker(workID int){ for task:=range p.JobsChannel{ task.Execute() //取到任務(wù)就執(zhí)行 fmt.Println("worker_id 為",workID) } } // 讓協(xié)程池開始真正的工作 func (p *Pool)run() { // 根據(jù)創(chuàng)建協(xié)程池的大小來創(chuàng)建協(xié)程工作 for i := 0; i < p.WorkerNum; i++ { go p.worker(i+1) } // 不斷遍歷外部的任務(wù)然后丟入到內(nèi)部的隊(duì)列去運(yùn)行 for task := range p.EntryChannel { p.JobsChannel<-task } }
4.3 Main函數(shù)
// 主函數(shù) 測試 func main(){ // 創(chuàng)建一些任務(wù) task:=NewTask(PrintTimeNow) // 創(chuàng)建協(xié)程池 pool:=NewPool(4) taskNum:=0 go func(taskNum int) { for{ // 不斷的向池子里寫入任務(wù)task,任務(wù)主要是打印當(dāng)前時(shí)間 pool.EntryChannel<-task // atomic.AddInt32(&taskNum,1) taskNum+=1 fmt.Println("當(dāng)前一共執(zhí)行了",taskNum,"個(gè)任務(wù)") } }(taskNum) pool.run() } // 業(yè)務(wù)邏輯 func PrintTimeNow()( err error){ fmt.Println(time.Now()) return }
到此這篇關(guān)于Golang協(xié)程池的實(shí)現(xiàn)與應(yīng)用的文章就介紹到這了,更多相關(guān)Go協(xié)程池內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang根據(jù)生日計(jì)算星座和屬相實(shí)例
這篇文章主要為大家介紹了golang根據(jù)生日計(jì)算星座和屬相的示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07Go項(xiàng)目配置管理神器之viper的介紹與使用詳解
viper是一個(gè)完整的?Go應(yīng)用程序的配置解決方案,它被設(shè)計(jì)為在應(yīng)用程序中工作,并能處理所有類型的配置需求和格式,下面這篇文章主要給大家介紹了關(guān)于Go項(xiàng)目配置管理神器之viper的介紹與使用,需要的朋友可以參考下2023-02-02Golang 空map和未初始化map的注意事項(xiàng)說明
這篇文章主要介紹了Golang 空map和未初始化map的注意事項(xiàng)說明,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04Go語言題解LeetCode724尋找數(shù)組的中心下標(biāo)
這篇文章主要為大家介紹了Go語言題解LeetCode724尋找數(shù)組的中心下標(biāo),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12Golang中空的切片轉(zhuǎn)化成 JSON 后變?yōu)?nbsp;null 問題的解決方案
在 Golang 中,經(jīng)常需要將其他類型(例如 slice、map、struct 等類型)的數(shù)據(jù)轉(zhuǎn)化為 JSON 格式,有時(shí)候轉(zhuǎn)化的結(jié)果并不是預(yù)期中的,例如將一個(gè)空的切片轉(zhuǎn)化為 JSON 時(shí),會變成"null",所以本文將給大家介紹一下解決方法,需要的朋友可以參考下2023-09-09解決Golang中ResponseWriter的一個(gè)坑
這篇文章主要介紹了解決Golang中ResponseWriter的一個(gè)坑,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04GO利用channel協(xié)調(diào)協(xié)程的實(shí)現(xiàn)
本文主要介紹了GO利用channel協(xié)調(diào)協(xié)程的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05