網(wǎng)站首頁 編程語言 正文
正常情況下,新激活的goroutine(協(xié)程)的結(jié)束過程是不可控制的,唯一可以保證終止goroutine(協(xié)程)的行為是main goroutine(協(xié)程)的終止。也就是說,我們并不知道哪個(gè)goroutine(協(xié)程)什么時(shí)候結(jié)束。
但很多情況下,我們正需要知道goroutine(協(xié)程)是否完成。這需要借助sync包的WaitGroup來實(shí)現(xiàn)。
WatiGroup是sync包中的一個(gè)struct類型,用來收集需要等待執(zhí)行完成的goroutine(協(xié)程)。下面是它的定義:
type WaitGroup struct { // Has unexported fields. } A WaitGroup waits for a collection of goroutines to finish. The main goroutine calls Add to set the number of goroutines to wait for. Then each of the goroutines runs and calls Done when finished. At the same time, Wait can be used to block until all goroutines have finished. A WaitGroup must not be copied after first use. func (wg *WaitGroup) Add(delta int) func (wg *WaitGroup) Done() func (wg *WaitGroup) Wait()
它有3個(gè)方法:
- Add():每次激活想要被等待完成的goroutine(協(xié)程)之前,先調(diào)用Add(),用來設(shè)置或添加要等待完成的goroutine(協(xié)程)數(shù)量
- 例如Add(2)或者兩次調(diào)用Add(1)都會(huì)設(shè)置等待計(jì)數(shù)器的值為2,表示要等待2個(gè)goroutine(協(xié)程)完成
- Done():每次需要等待的goroutine(協(xié)程)在真正完成之前,應(yīng)該調(diào)用該方法來人為表示goroutine(協(xié)程)完成了,該方法會(huì)對(duì)等待計(jì)數(shù)器減1
- Wait():在等待計(jì)數(shù)器減為0之前,Wait()會(huì)一直阻塞當(dāng)前的goroutine(協(xié)程)
也就是說,Add()用來增加要等待的goroutine(協(xié)程)的數(shù)量,Done()用來表示goroutine(協(xié)程)已經(jīng)完成了,減少一次計(jì)數(shù)器,Wait()用來等待所有需要等待的goroutine(協(xié)程)完成。
下面是一個(gè)示例,通過示例很容易理解。
package main import ( "fmt" "sync" "time" ) func process(i int, wg *sync.WaitGroup) { fmt.Println("started Goroutine ", i) time.Sleep(2 * time.Second) fmt.Printf("Goroutine %d ended\n", i) wg.Done() } func main() { no := 3 var wg sync.WaitGroup for i := 0; i < no; i++ { wg.Add(1) go process(i, &wg) } wg.Wait() fmt.Println("All go routines finished executing") }
上面激活了3個(gè)goroutine,每次激活goroutine之前,都先調(diào)用Add()方法增加一個(gè)需要等待的goroutine計(jì)數(shù)。每個(gè)goroutine都運(yùn)行process()函數(shù),這個(gè)函數(shù)在執(zhí)行完成時(shí)需要調(diào)用Done()方法來表示goroutine的結(jié)束。激活3個(gè)goroutine后,main goroutine會(huì)執(zhí)行到Wait(),由于每個(gè)激活的goroutine運(yùn)行的process()都需要睡眠2秒,所以main goroutine在Wait()這里會(huì)阻塞一段時(shí)間(大約2秒),當(dāng)所有g(shù)oroutine都完成后,等待計(jì)數(shù)器減為0,Wait()將不再阻塞,于是main goroutine得以執(zhí)行后面的Println()。
還有一點(diǎn)需要特別注意的是process()中使用指針類型的*sync.WaitGroup
作為參數(shù),這里不能使用值類型的sync.WaitGroup
作為參數(shù),因?yàn)檫@意味著每個(gè)goroutine都拷貝一份wg,每個(gè)goroutine都使用自己的wg。這顯然是不合理的,這3個(gè)goroutine應(yīng)該共享一個(gè)wg,才能知道這3個(gè)goroutine都完成了。實(shí)際上,如果使用值類型的參數(shù),main goroutine將會(huì)永久阻塞而導(dǎo)致產(chǎn)生死鎖。
原文鏈接:https://www.cnblogs.com/f-ck-need-u/p/10004787.html
相關(guān)推薦
- 2022-05-26 簡(jiǎn)單聊一聊SQL注入及防止SQL注入_數(shù)據(jù)庫其它
- 2022-09-14 Android自定義視圖中圖片的處理_Android
- 2022-08-30 C語言深入探究sizeof與整型數(shù)據(jù)存儲(chǔ)及數(shù)據(jù)類型取值范圍_C 語言
- 2023-10-28 go帶緩沖chan實(shí)現(xiàn)消息隊(duì)列功能_Golang
- 2023-03-25 React?數(shù)據(jù)獲取條件競(jìng)爭(zhēng)原理解析_React
- 2022-04-28 .net項(xiàng)目使用日志框架log4net_實(shí)用技巧
- 2023-07-26 ndoe中express框架的基本使用,接收get、post請(qǐng)求,以及處理回調(diào)地獄的優(yōu)雅解決方法
- 2022-07-11 搭建spring MVC框架,完成和servlet相似的操作
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支