Golang 語言控制并發(fā) Goroutine的方法
goroutine 是 Go語言中的輕量級(jí)線程實(shí)現(xiàn),由 Go 運(yùn)行時(shí)(runtime)管理。Go 程序會(huì)智能地將 goroutine 中的任務(wù)合理地分配給每個(gè) CPU。
01介紹
Golang 語言的優(yōu)勢(shì)之一是天生支持并發(fā),我們?cè)?Golang 語言開發(fā)中,通常使用的并發(fā)控制方式主要有 Channel,WaitGroup 和 Context,本文我們主要介紹一下 Golang 語言中并發(fā)控制的這三種方式怎么使用?關(guān)于它們各自的詳細(xì)介紹在之前的文章已經(jīng)介紹過,感興趣的讀者朋友們可以按需翻閱。
02Channel
在 Golang 語言中,Channel 不僅可以用于協(xié)程之間通信,還可以使用 Channel 控制子協(xié)程,而且使用 Channel 實(shí)現(xiàn)并發(fā)控制比較簡(jiǎn)單,比如以下示例,我們?cè)?Golang 應(yīng)用程序中啟動(dòng)兩個(gè)協(xié)程,分別是主協(xié)程和子協(xié)程,主協(xié)程需要等待子協(xié)程運(yùn)行結(jié)束后再退出程序。
示例代碼:
func main () { done := make(chan struct{}) go func() { fmt.Println("goroutine run over") done <- struct{}{} }() <- done fmt.Println("main goroutine run over") }
閱讀上面這段代碼,我們?cè)谧?goroutine 運(yùn)行結(jié)束后,通過 Channel 通知主 goroutine 退出程序,實(shí)際上也可以反過來處理,主 goroutine 通知子 goroutine 退出程序,主 goroutine 向 channel 中發(fā)送數(shù)據(jù),子 goroutine 等待接收 channel 中的數(shù)據(jù)。
03sync.WaitGroup
如果在 Golang 應(yīng)用程序中,需要讓主 goroutine 等待多個(gè) goroutine 都運(yùn)行結(jié)束后再退出程序,我們應(yīng)該怎么實(shí)現(xiàn)呢?是的,同樣可以使用 Channel 實(shí)現(xiàn),但是,有一個(gè)更優(yōu)雅的實(shí)現(xiàn)方式,那就是 WaitGroup,顧名思義,WaitGroup 就是等待一組 goroutine 運(yùn)行結(jié)束。
示例代碼:
func main () { wg := sync.WaitGroup{} wg.Add(10) for i := 0; i < 10; i++ { go func(id int) { fmt.Println(id, "運(yùn)行結(jié)束") wg.Done() }(i) } wg.Wait() fmt.Println("main goroutine run over") }
閱讀上面這段代碼,我們啟動(dòng) 10 個(gè)子 goroutine,主 goroutine 需要等待 10 個(gè)子 goroutine 都運(yùn)行結(jié)束后再退出程序,我們使用的是 WaitGroup,它有三個(gè)方法,分別是 Add、Done 和 Wait,實(shí)際上 WaitGroup 維護(hù)了一個(gè)計(jì)數(shù)器,這三個(gè)方法都是圍繞這個(gè)計(jì)數(shù)器工作,Add 用于設(shè)置計(jì)數(shù)器的數(shù)值,Done 用于扣減計(jì)數(shù)器的數(shù)值,Wait 在計(jì)數(shù)器數(shù)值為 0 之前一直阻塞。關(guān)于 WaitGroup 的源碼解讀,在之前的文章中已介紹過,限于篇幅,這里就不再贅述。
04Context
Channel 和 WaitGroup 通常用于父子兩個(gè)層級(jí)的 goroutine 的應(yīng)用程序的并發(fā)控制中,如果在 Golang 應(yīng)用程序中,子協(xié)程繼續(xù)派生出協(xié)程,我們應(yīng)該怎么控制呢?這種多級(jí) goroutine 的應(yīng)用程序,我們可以使用 Context 實(shí)現(xiàn)并發(fā)控制。
示例代碼:
func main() { ctx, cancel := context.WithCancel(context.Background()) go firstCtx(ctx) time.Sleep(5 * time.Second) fmt.Println("stop all sub goroutine") cancel() time.Sleep(5 * time.Second) } func firstCtx(ctx context.Context) { go secondCtx(ctx) for { select { case <-ctx.Done(): fmt.Println("first done") return default: fmt.Println("first running") time.Sleep(2 * time.Second) } } } func secondCtx(ctx context.Context) { for { select { case <-ctx.Done(): fmt.Println("second done") return default: fmt.Println("second running") time.Sleep(2 * time.Second) } } }
閱讀上面這段代碼,在子協(xié)程 firstCtx 啟動(dòng)子協(xié)程 secondCtx,主 goroutine 創(chuàng)建 context,并把 context 傳遞到所有子協(xié)程,然后主 goroutine 通過調(diào)用 cancle 停掉所有子協(xié)程。
05總結(jié)
本文我們介紹了不同場(chǎng)景中分別適合哪種控制并發(fā) goroutine 的方式,其中,channel 適合控制少量 并發(fā) goroutine,WaitGroup 適合控制一組并發(fā) goroutine,而 context 適合控制多級(jí)并發(fā) goroutine。
到此這篇關(guān)于Golang 語言控制并發(fā) Goroutine的方法的文章就介紹到這了,更多相關(guān)Golang并發(fā)控制Goroutine內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- golang gin 框架 異步同步 goroutine 并發(fā)操作
- Go語言中的并發(fā)goroutine底層原理
- Go并發(fā)編程之goroutine使用正確方法
- Go 并發(fā)編程Goroutine的實(shí)現(xiàn)示例
- golang并發(fā)編程中Goroutine 協(xié)程的實(shí)現(xiàn)
- Go中Goroutines輕量級(jí)并發(fā)的特性及效率探究
- 使用Go?goroutine實(shí)現(xiàn)并發(fā)的Clock服務(wù)
- Go語言使用goroutine及通道實(shí)現(xiàn)并發(fā)詳解
- Go 控制協(xié)程(goroutine)的并發(fā)數(shù)量
- Go語言使用Goroutine并發(fā)打印的項(xiàng)目實(shí)踐
相關(guān)文章
詳解Golang互斥鎖內(nèi)部實(shí)現(xiàn)
本篇文章主要介紹了詳解Golang互斥鎖內(nèi)部實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06Go調(diào)用opencv實(shí)現(xiàn)圖片矯正的代碼示例
這篇文章主要為大家詳細(xì)介紹了Go調(diào)用opencv實(shí)現(xiàn)圖片矯正的代碼示例,文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-09-09Go方法簡(jiǎn)單性和高效性的充分體現(xiàn)詳解
本文深入探討了Go語言中方法的各個(gè)方面,包括基礎(chǔ)概念、定義與聲明、特性、實(shí)戰(zhàn)應(yīng)用以及性能考量,文章充滿技術(shù)深度,通過實(shí)例和代碼演示,力圖幫助讀者全面理解Go方法的設(shè)計(jì)哲學(xué)和最佳實(shí)踐2023-10-10詳解golang中發(fā)送http請(qǐng)求的幾種常見情況
這篇文章主要介紹了詳解golang中發(fā)送http請(qǐng)求的幾種常見情況,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12Go語言學(xué)習(xí)之結(jié)構(gòu)體和方法使用詳解
這篇文章主要為大家詳細(xì)介紹了Go語言中結(jié)構(gòu)體和方法的使用,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Go語言有一定的幫助,需要的可以參考一下2022-04-04