玩轉 Go 語言并發編程:Goroutine 實戰指南

一、goroutine 池

  • 本質上是生產者消費者模型
  • 在工作中我們通常會使用可以指定啟動的 goroutine 數量-worker pool 模式,控制 goroutine 的數量,防止 goroutine 泄漏和暴漲
  • 一個簡易的 work pool 示例代碼如下:
package mainimport ("fmt""time"
)func worker (id int, jobs <-chan int, results chan <- int) {//消費者消費任務for j := range jobs {fmt.Printf("worker:%d start job:%d\n", id, j)time.Sleep(time.Second)fmt.Printf("worker:%d end job:%d\n", id, j)results <- j * 2}}func main() {jobs := make(chan int, 100)results := make(chan int, 100)// 1)開啟3個goroutine,作為消費者消費 jobs中任務for w := 1; w <= 3; w++ {go worker(w, jobs, results)}// 2)5個任務(生產者生產任務)for j := 1; j <= 5; j++ {jobs <- j}close(jobs)// 3)輸出結果for a := 1; a <= 5; a++ {v := <-resultsfmt.Println(v)}
}

二、打印奇數偶數

1、一個無緩沖管道實現
  • 首先我們這里通過 make(chan int),開辟的通道是一種無緩沖通道
  • 所以當對這個緩沖通道寫的時候,會一直阻塞等到某個協程對這個緩沖通道讀
  • 而這里我講 ch <- true 理解為色號給你吃,它卻是需要等到某個協程讀了才能繼續運行
package mainimport ("fmt""sync"
)var wg sync.WaitGroupfunc printJS(ch chan bool) {defer wg.Done()for i := 1; i <= 9; i += 2 {fmt.Println("js", i)   // 奇數先打印ch <- true         // 給偶數打印函數一個信號(需要等到某個協程讀了再能繼續運行)<-ch}
}func printOS(ch chan bool) {defer wg.Done()for i := 2; i <= 10; i += 2 {<-ch  // 偶數等待奇數函數 向chan發送信號fmt.Println("os", i)ch <- false         // 給奇數打印函數一個信號(需要等到某個協程讀了再能繼續運行)}
}func main() {// 新建一個無緩沖管道(無緩沖管道只能一個協程寫入,然后另外一個協程來讀取)ch := make(chan bool)wg.Add(2)go printJS(ch)go printOS(ch)wg.Wait()
}
2、兩個無緩沖管道實現
package mainimport ("fmt""sync"
)var ch1 = make(chan bool)
var ch2 = make(chan bool)
var wg sync.WaitGroupfunc go1JS() {defer wg.Done()for i := 1; i <= 10; i += 2 {<-ch1 // ch1獲取數據成功就不阻塞,進行下一步fmt.Println(i)ch2 <- true // 向ch2發送信號,打印奇數}<-ch1  // 因為main函數最初向ch1放入了一個數據,所以最后打印結束后取出,否則死鎖
}
func go2OS() {defer wg.Done()for i := 2; i <= 10; i += 2 {<-ch2fmt.Println(i)ch1 <- true}
}
func main() {wg.Add(2)go go1JS()  // 打印奇數go go2OS()  // 打印偶數ch1 <- true // 先讓奇數的協程執行wg.Wait()
}

三、超時控制

1、基礎版
package mainimport ("fmt""math/rand""time"
)// 在 main 函數里調用給定的 rpc 方法,并設置超時時間為 10 秒
// 在等待過程中如果超時則取消等待并打印 "timeout" ,如果沒有超時則打印出 rpc 的返回結果。
// rpc 方法不可以修改
func main() {ch := make(chan bool)var ret intgo func() {ret = rpc()<-ch}()count := 0for count < 10 {if ret != 0 {fmt.Println(ret)break}time.Sleep(time.Second)count += 1}if count >= 10 {ch <- falsefmt.Println("timeout")}
}// 這是你要調用的方法,可以看作一個黑盒
// 它的耗時是 1~15 秒內的隨機數
// 最終返回一個隨機的 int 類型
func rpc() int {cost := rand.Intn(15) + 1fmt.Printf("rpc will cost %d seconds\n", cost)time.Sleep(time.Duration(cost) * time.Second)return cost
}func init() {rand.Seed(time.Now().UnixNano())
}
2、time.After控制超時
package mainimport ("fmt""time"
)func main() {workDoneCh := make(chan bool, 1)go func() {LongTimeWork()     //這是我們要控制超時的函數workDoneCh <- true // 函數正常執行結束給 chan信號正常退出}()select {case <-workDoneCh: // 當協程執行完成后會向這個 channel 發送一個數據,收到即可結束fmt.Println("Success!")case <-time.After(3 * time.Second): //timeout到來fmt.Println("timeout") // 3s無返回超時退出}
}func LongTimeWork() {time.Sleep(time.Second * 2)
}

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

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

相關文章

小程序跳轉tabbar,tabbar頁面不刷新

文章地址&#xff1a;12.小程序 之切換到tabBar頁面不刷新問題_360問答 解決辦法備份&#xff1a; wx.switchTab&#xff1a;跳轉到 tabBar 頁面&#xff0c;并關閉其他所有非 tabBar 頁面 wx.reLaunch&#xff1a;關閉所有頁面&#xff0c;打開到應用內的某個頁面。 wx.reLa…

解決微信小程序中 ‘nbsp;‘ 空格不生效的問題

在微信小程序開發中&#xff0c;我們經常會使用 來表示一個空格。這是因為在 HTML 中&#xff0c;空格會被解析為一個普通字符&#xff0c;而不會產生實際的空白間距。而 是一種特殊的字符實體&#xff0c;它被解析為一個不可見的空格&#xff0c;可以在頁面上產生真正的空…

力扣70. 爬樓梯

動態規劃 思路&#xff1a; 使用遞歸比較容易理解&#xff0c; f(n) f(n - 1) f(n - 2)&#xff1b; 到剩余1級臺階有 f(n - 1)&#xff0c;到剩余2級臺階有 f(n-2)&#xff1b;邊界情況是 n 0, f(0) 1n 1, f(1) 1n 2, f(2) 2 遞歸代碼實現&#xff1a; class Soluti…

Axure RP 9 入門教程

1. Axure簡介 Axure 是一個交互式原型設計工具&#xff0c;可以幫助用戶創建復雜的交互式應用程序和網站。Axure 能夠讓用戶快速構建出具有高度可交互性的原型&#xff0c;可以在團隊中進行協作、分享和測試。 使用 Axure 可以設計出各種不同類型的原型&#xff0c;包括網站、移…

系列十五、搭建redis集群

一、概述 上篇文章介紹了redis集群的相關知識&#xff0c;本章實戰演示redis的集群環境的詳細搭建步驟。如果幫助到了你&#xff0c;請點贊 收藏 關注&#xff01;有疑問的話也可以評論區交流。 二、搭建步驟 2.1、預備知識 判斷一個集群中的節點是否可用&#xff0c;是集群…

【SpringBoot篇】詳解基于Redis實現短信登錄的操作

文章目錄 &#x1f970;前言&#x1f6f8;StringRedisTemplate&#x1f339;使用StringRedisTemplate?常用的方法 &#x1f6f8;為什么我們要使用Redis代替Session進行登錄操作&#x1f386;具體使用?編寫攔截器?配置攔截器&#x1f33a;基于Redis實現發送手機驗證碼操作&am…

EarCMS 前臺任意文件上傳漏洞復現

0x01 產品簡介 EarCMS是一個APP內測分發系統的平臺。 0x02 漏洞概述 EarCMS前臺put_upload.php中,存在pw參數硬編碼問題,同時sql語句pdo使用錯誤,沒有有效過濾sql語句,可以控制文件名和后綴,導致可以任意文件上傳。 0x03 復現環境 FOFA:app="EearCMS" 0x0…

Flutter實現自定義二級列表

在Flutter開發中&#xff0c;其實系統已經給我們提供了一個可靠的二級列表展開的API&#xff08;ExpansionPanelList&#xff09;&#xff0c;我們先看系統的二級列表展開效果&#xff0c;一次只能展開一個&#xff0c;用ExpansionPanelList.radio實現 由此可見&#xff0c;已經…

容器化升級對服務有哪些影響?

容器技術是近幾年計算機領域的熱門技術&#xff0c;特別是隨著各種云服務的發展&#xff0c;越來越多的服務運行在以 Docker 為代表的容器之內。 本文我們就來分享一下容器化技術相關的知識。 容器化技術簡介 相比傳統虛擬化技術&#xff0c;容器技術是一種更加輕量級的操作…

分治法求最大子列和

給定N個整數的序列{ A1, A2, …, AN}&#xff0c;其中可能有正數也可能有負數&#xff0c;找出其中連續的一個子數列&#xff08;不允許空序列&#xff09;&#xff0c;使它們的和盡可能大&#xff0c;如果是負數&#xff0c;則返回0。使用下列函數&#xff0c;完成分治法求最大…

CorelDRAW軟件2024版本好用嗎?有哪些功能優勢

CorelDRAW是一款綜合性強大的專業平面設計軟件&#xff0c;其功能覆蓋了矢量圖形設計、高級文字編輯、精細繪圖以及多頁文檔和頁面設計。該軟件不僅適用于廣告設計、包裝設計&#xff0c;還廣泛應用于出版、網頁設計和多媒體制作等多個領域。下面就給大家介紹一下CorelDRAW這款…

0012Java安卓程序設計-ssm記賬app

文章目錄 **摘要**目 錄系統設計5.1 APP端&#xff08;用戶功能&#xff09;5.2后端管理員功能模塊開發環境 編程技術交流、源碼分享、模板分享、網課分享 企鵝&#x1f427;裙&#xff1a;776871563 摘要 網絡的廣泛應用給生活帶來了十分的便利。所以把記賬管理與現在網絡相…

arkts編譯報錯-arkts-limited-stdlib錯誤【Bug已完美解決-鴻蒙開發】

文章目錄 項目場景:問題描述原因分析:解決方案:適配指導案例此Bug解決方案總結項目場景: arkts編譯報錯-arkts-limited-stdlib錯誤。 我用Deveco studio4.0 beta2開發應用,報arkts-limited-stdlib錯誤 報錯內容為: ERROR: ArKTS:ERROR File: D:/prRevivw/3792lapplica…

[Verilog]用Verilog實現串并轉換/并串裝換

用Verilog實現串并轉換/并串裝換 摘要 一、串并轉換模塊 串轉并就是將低3位信號和輸入信號一起賦值。因為經過轉換后&#xff0c;碼元速率會將為原來四分之一&#xff0c;所以設置4分頻時鐘&#xff0c;將其輸出。而并轉串就是不斷右移&#xff0c;取高位輸出。 module serial…

Android 11.0 systemui鎖屏頁面時鐘顯示樣式的定制功能實現

1.前言 在11.0的系統ROM定制化開發中,在進行systemui的相關開發中,當開機完成后在鎖屏頁面就會顯示時間日期的功能,由于 開發產品的需求要求時間顯示周幾上午下午接下來就需要對鎖屏顯示時間日期的相關布局進行分析,然后實現相關功能 效果圖如圖: 2.systemui鎖屏頁面時鐘顯…

mysql原理--B+樹索引

1.沒有索引的查找 1.1.在一個頁中的查找 (1). 以主鍵為搜索條件 可以在 頁目錄 中使用二分法快速定位到對應的槽&#xff0c;然后再遍歷該槽對應分組中的記錄即可快速找到指定的記錄。 (2). 以其他列作為搜索條件 這種情況下只能從 最小記錄 開始依次遍歷單鏈表中的每條記錄&am…

值得收藏的練習打字網站

本文對一些好用的練習打字的網站進行了匯總整理&#xff0c;方便大家使用 一&#xff1a;程序猿練習打字&#xff1a; 1.Typing Practice for Programmers http://Typing.io 是程序員的打字導師。它的練習課程基于開源代碼&#xff0c;讓你在不斷的練習中提升自己的碼字速度…

Python:核心知識點整理大全15-筆記

目錄 ?編輯 7.3.2 刪除包含特定值的所有列表元素 pets.py 7.3.3 使用用戶輸入來填充字典 mountain_poll.py 7.4 小結 第8章 函 數 8.1 定義函數 greeter.py 8.1.1 向函數傳遞信息 8.1.2 實參和形參 8.2.1 位置實參 2. 位置實參的順序很重要 8.2.2 關鍵字實參 往…

Ansible通過kubernetes.core.k8s_info和kubernetes.core.k8s訪問OCP

文章目錄 環境OCPClient&#xff08;Ansible控制節點&#xff09; 步驟準備工作在client端配置ssh免密登錄OCP端在client端安裝Ansible kubernetes.core.k8s_info第1次嘗試在OCP端安裝python和pip3在OCP端安裝kubernetes在OCP端安裝PyYAML第2次嘗試在OCP端配置config文件第3次嘗…

計算機循環神經網絡(RNN)

計算機循環神經網絡&#xff08;RNN&#xff09; 一、引言 循環神經網絡&#xff08;RNN&#xff09;是一種常見的深度學習模型&#xff0c;適用于處理序列數據&#xff0c;如文本、語音、時間序列等。RNN通過捕捉序列數據中的時間依賴關系和上下文信息&#xff0c;能夠解決很…