用go語言實現一個有界協程池

寫在文章開頭

本篇文章算是對go語言系列的一個收尾,通過go語言實現一個實現一個簡單的有界協程池。

在這里插入圖片描述

Hi,我是 sharkChili ,是個不斷在硬核技術上作死的 java coder ,是 CSDN的博客專家 ,也是開源項目 Java Guide 的維護者之一,熟悉 Java 也會一點 Go ,偶爾也會在 C源碼 邊緣徘徊。寫過很多有意思的技術博客,也還在研究并輸出技術的路上,希望我的文章對你有幫助,非常歡迎你關注我的公眾號: 寫代碼的SharkChili

因為近期收到很多讀者的私信,所以也專門創建了一個交流群,感興趣的讀者可以通過上方的公眾號獲取筆者的聯系方式完成好友添加,點擊備注 “加群” 即可和筆者和筆者的朋友們進行深入交流。

在這里插入圖片描述

詳解go語言協程池的實現

整體交互流程設計

我們希望創建一個協程池,該協程池大小由用戶決定,主協程不斷生產任務并投遞到channel中,協程池收到任務后,如果發現沒有對應處理的協程worker則創建一個協程并處理傳入的任務,反之這些任務就會有序得等待協程有序調度執行:

在這里插入圖片描述

定義worker

基于上圖我們給出worker的接口定義,按照我們的實現每一個任務都是一個worker,協程池的協程可以從channel中得到對應的Worker 并執行其Task方法:

type Worker interface {Task()
}

聲明協程池

基于worker我們封裝一個worker池,也就是本文提到的協程池,可以看到該Pool有一個worker的通道用于存放主協程投遞進來的任務,而wg則用于控制協程的生命周期,這一點我們會在后續的工作代碼中詳盡說明:

type Pool struct {//記錄主協程投遞的任務work chan Worker//控制工作協程的生命周期wg   sync.WaitGroup
}

創建協程池

有了協程池的定義之后,我們就可以編寫協程池的,可以看到我們可以通過入參決定channel和協程的大小,通過傳入maxGoroutines 設置wg的大小,當協程都沒有任務執行時,才會調用wgDone方法,確保所有任務執行完成后,主協程才能退出:

func New(maxGoroutines int) *Pool {//創建指定協程數的channelp := Pool{work: make(chan Worker, maxGoroutines),}//基于協程數創建倒計時門閂p.wg.Add(maxGoroutines)//創建maxGoroutines個協程獲取channel的任務執行for i := 0; i < maxGoroutines; i++ {go func() {for w := range p.work {w.DoTask()}//任務執行完成且channel關閉之后,按下倒計時門閂p.wg.Done()}()}//返回pool的指針return &p
}

投遞任務

當我們需要投遞任務時,就可以將自實現的worker投遞到channle中:

func (p *Pool) Run(w Worker) {//將任務w投遞到channel中p.work <- w
}

關閉協程池

最后我們給出關于協程池關閉的實現,其邏輯比較簡單:

  1. 關閉channel不再接受新任務。
  2. 調用waitGroupWait方法等待所有協程執行完再返回。
func (p *Pool) ShutDown() {close(p.work)p.wg.Wait()
}

測試代碼

最后我們給出本文的測試代碼,使用示例比較簡單:

  1. 定義一個姓名切片,作為測試數據。
  2. 創建一個名為namePrinter 的結構體,內部包含name屬性,該結構體會繼承Worker實現打印姓名的Task方法。
  3. 創建一個channel和協程大小都為2的Pool
  4. 通過多協程循環遍歷name切片并將其封裝成namePrinter投遞到chanel中。
  5. 協程池的協程消費這些打印姓名的任務。
  6. 調用shutDown方法等待協程池內部協程工作完成后退出主協程。
// 創建一個測試用的姓名切片
var names = []string{"user.go-1","user.go-2","user.go-3","user.go-4","user.go-5",
}// 實現worker接口 打印姓名
type namePrinter struct {name string
}func (n *namePrinter) Task() {fmt.Println(n.name)time.Sleep(time.Second)
}func main() {//創建還有兩個協程的poolp := work.New(2)//創建main協程的倒計時門閂var wg sync.WaitGroupwg.Add(100 * len(names))//多協程投遞任務到poolfor i := 0; i < 100; i++ {for _, name := range names {np := namePrinter{name: name,}go func() {p.Run(&np)wg.Done()}()}}//等待任務投遞完成wg.Wait()fmt.Println("執行結束,關閉pool")p.ShutDown()}

小結

自此,本文基于go語言的并發技術實現了一個簡單的協程池,希望對你有所幫助。而go語言系列也到此告一段落。

我是 sharkchiliCSDN Java 領域博客專家開源項目—JavaGuide contributor,我想寫一些有意思的東西,希望對你有幫助,如果你想實時收到我寫的硬核的文章也歡迎你關注我的公眾號: 寫代碼的SharkChili
因為近期收到很多讀者的私信,所以也專門創建了一個交流群,感興趣的讀者可以通過上方的公眾號獲取筆者的聯系方式完成好友添加,點擊備注 “加群” 即可和筆者和筆者的朋友們進行深入交流。

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/16757.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/16757.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/16757.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HDR視頻相關標準-HDR vivid(二)

上文介紹了HDRvivid的一些技術。今天從全局角度來看看HDR視頻的處理流程&#xff0c;HDR視頻系統&#xff0c;即建立一個比SDR視頻更大的色彩/亮度坐標體系&#xff0c;并改變系統的傳輸函數&#xff0c;以再現更大的色域(WCG)和更高的亮度動態范圍。 菁彩 HDR技術的專業術語 …

【ROSUbuntu】常用工具合集

1. 源 ADM64 ubuntu | 鏡像站使用幫助 | 清華大學開源軟件鏡像站 | Tsinghua Open Source Mirror arm64 ubuntu-ports | 鏡像站使用幫助 | 清華大學開源軟件鏡像站 | Tsinghua Open Source Mirror 2. FileZilla sudo apt-get install filezilla 3. Nomachine8 AMD64

操作系統實戰(四)(linux+C語言)

目錄 實驗目的 前提知識 實驗題目 題目分析 實驗程序 頭文件 頭文件實現 核心代碼文件 &#xff08;各類進程&#xff09; 生產者 抽煙者A 抽煙者B 抽煙者C makefile文件 實驗運行 運行結果分析 總結 實驗目的 加深對并發協作進程同步與互斥概念的理解&…

【DNS】linux 中讓系統 NetworkManager 不自動生成無效的 DNS

1. 問題背景 一些系統安裝之后會自動覆蓋/添加無效 DNS 設置&#xff0c;導致反而無法上網。 2. 解決方法 修改 /etc/NetworkManager/NetworkManager.conf 文件&#xff0c;在 [main] 部分下添加或修改如下&#xff1a; [main] dnsnone然后用以下命令重啟 NetworkManager …

C# 類(Class)

1. 類的基本概念 在C#中,類是一種引用類型,用于定義對象的模板。類可以包含字段(Field)、屬性(Property)、方法(Method)、事件(Event)等成員。對象是類的實例,通過類的構造函數創建。 2. 類的聲明和使用 你可以使用class關鍵字來聲明一個類: public class Pers…

簡述Vue初始化過程中都做了什么?

在Vue的初始化過程中&#xff08;new Vue(options)&#xff09;&#xff0c;主要執行了以下幾個步驟&#xff1a; 創建Vue實例&#xff1a; 使用new Vue(options)來創建一個新的Vue實例。這里的options是一個包含Vue實例初始化所需選項的對象。 合并配置&#xff1a; Vue會將傳…

代碼隨想錄算法訓練營day34 | 455.分發餅干、376. 擺動序列、53. 最大子序和

理論基礎 貪心的本質是選擇每一階段的局部最優&#xff0c;從而達到全局最優。 刷題或者面試的時候&#xff0c;手動模擬一下感覺可以局部最優推出整體最優&#xff0c;而且想不到反例&#xff0c;那么就試一試貪心。 455.分發餅干 result和j變化一致&#xff0c;可以去除一…

Jenkins配置(插件/角色/憑證)

目錄 傳送門前言一、Jenkins插件管理1、更換為國內下載源2、中文漢化插件下載&#xff08;不推薦&#xff09;3、低版本Jenkins爆紅插件安裝4、低版本Jenkins插件持續報錯解決辦法 二、Jenkins用戶角色三、Jenkins憑證管理&#xff08;svn/git&#xff09;1、Username with pas…

Qt hide()和setVisible(false)區別

前言 在一些場景下&#xff0c;我們需要控制控件的顯示與隱藏&#xff0c;QWidget 類提供了兩種方法來隱藏控件hide() 和 setVisible(false)。那么他們有何區別呢&#xff1f; widget->hide(); // &#xff1f; widget->setVisible(false);hide() 和 setVisible(false…

【本周面試問題總結】

01.如何判斷鏈表中是否有環 ①窮舉遍歷&#xff1a;從頭節點開始&#xff0c;依次遍歷單鏈表中的每一個節點。每遍歷到一個新節點&#xff0c;將新節點和此前節點進行比較&#xff0c;若已經存在則說明已被遍歷過&#xff0c;鏈表有環。 ②快慢指針&#xff1a;創建兩個指針&am…

NIO流(多路復用技術)

目錄 什么是NIO使用場景 NIO(new IO)相關包路徑NIO的實現基礎NIO的核心組件Buffer緩沖區詳解數據如何從磁盤讀到用戶進程 ChannelChannel的使用 其他組件字符集和Charset文件鎖NIO工具類使用Files的FileVisitor遍歷文件和目錄使用WatchService監控文件變化訪問文件屬性 什么是N…

什么樣的無線麥克風好?一文看懂哪種麥克風降噪效果好

作為視頻創作者&#xff0c;拍攝視頻除了要注意拍攝的畫質外&#xff0c;聲音的錄制也很重要。聲音錄制的清晰度也會直接影響整個作品的整體水平&#xff0c;要想錄的聲音清晰&#xff0c;有專業級錄制效果&#xff0c;必須選好麥克風&#xff0c;而無線領夾麥克風&#xff0c;…

craco-less 插件如何使用

craco-less 是一個用于 Create React App (CRA) 的插件&#xff0c;它允許你在項目中無縫集成和使用 Less 作為樣式預處理器。以下是如何在你的 React 項目中配置并使用 craco-less 插件的步驟&#xff1a; 安裝所需依賴 首先&#xff0c;確保你已經安裝了 create-react-app …

SCSS入門指南:基本語法與高效用法

關于SCSS&#xff08;Sassy CSS&#xff09;基本使用的文章概述&#xff1a;### 1. SCSS簡介* SCSS是一種CSS的擴展語言&#xff0c;它允許開發者使用更強大、更靈活的語法來編寫樣式表。* SCSS提供了變量、嵌套規則、混合宏等高級功能&#xff0c;使得CSS代碼更加模塊化和可維…

單片機控制語音芯片的錄放音系統的設計

[摘 要]:介紹了由Flash單片機AT89C2051及數碼語音芯片ISD2560組成的電腦語音系統設計出了系統的硬件電路,給出了錄、放音實用的源程序。目前基于單片微機的語音系統的應用越來越廣泛,如電腦語音鐘、語音型數字萬用表、手機話費查詢系統、排隊機、監控系統語音報警以及公共汽…

碩士大論文參考文獻標準格式

碩士大論文參考文獻標準格式 期刊會議碩士論文 參考文獻往往是格式的重災區&#xff0c;因為谷歌學術默認的引用并不一定是完全正確的 注意事項&#xff1a; 統一所有參考文獻的名稱格式&#xff0c;要么名稱全部用首字母大寫&#xff0c;要么全部只有第一個單詞的首字母大寫…

【工具分享】Annabelle勒索病毒解密工具

前言 Annabelle勒索病毒靈感來自恐怖電影系列 Annabelle。除了文件加密功能外&#xff0c;Annabelle 勒索軟件還會試圖禁用防火墻&#xff0c;強制停止一系列正在運行程序&#xff0c;通過連接的 USB 驅動器進行傳播。 特征 勒索內容&#xff1a; Annabelle 使用 AES256 CBC 加…

【Linux】線程同步和生產者-消費者模型

目錄 一. 線程同步1. 條件變量2. 條件變量接口條件變量的創建及初始化條件變量的銷毀條件變量等待條件變量喚醒 3. 條件變量同步解決搶占問題 二. 生產者-消費者模型1. 什么是生產者-消費者模型2. 為什么要使用生產者-消費者模型3. 生產者-消費者模型特點4. 基于阻塞隊列實現生…

技術前沿:三品PLM系統引領工程變更管理新趨勢

引言 在當今快速變化的制造行業&#xff0c;產品生命周期管理&#xff08;PLM&#xff09;系統已成為企業不可或缺的工具之一。PLM系統不僅幫助企業優化產品開發流程&#xff0c;還對工程變更管理&#xff08;ECM&#xff09;起著至關重要的作用。本文將探討PLM系統在工程變更…

解決ssh報錯,.ssh/id_rsa: No such file or directory Permission denied (publickey)

拉取依賴或者代碼時說沒有權限 首先我們可以看到的是這個報錯但是我們的遠程確實配置ssh密鑰 首先我們可以看到的是這個報錯 但是我們的遠程確實配置ssh密鑰 我們可以在我們項目路徑下添加一下我們的私鑰如&#xff1a; 首先確定我們ssh是正常啟動的eval $(ssh-agent)我們可以…