新聞中心
[[408188]]
01介紹
Golang 語言的優(yōu)勢(shì)之一是天生支持并發(fā),我們?cè)?Golang 語言開發(fā)中,通常使用的并發(fā)控制方式主要有 Channel,WaitGroup 和 Context,本文我們主要介紹一下 Golang 語言中并發(fā)控制的這三種方式怎么使用?關(guān)于它們各自的詳細(xì)介紹在之前的文章已經(jīng)介紹過,感興趣的讀者朋友們可以按需翻閱。

創(chuàng)新互聯(lián)公司長(zhǎng)期為上1000+客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為鎮(zhèn)賚企業(yè)提供專業(yè)的成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、外貿(mào)營(yíng)銷網(wǎng)站建設(shè),鎮(zhèn)賚網(wǎng)站改版等技術(shù)服務(wù)。擁有十余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。
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。
本文轉(zhuǎn)載自微信公眾號(hào)「Golang語言開發(fā)?!?,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系Golang語言開發(fā)棧公眾號(hào)。
新聞標(biāo)題:Golang語言怎么控制并發(fā)Goroutine?
網(wǎng)站URL:http://www.5511xx.com/article/cogcohe.html


咨詢
建站咨詢
