并發編程技巧:Go WaitGroup的高級用法
在并發編程中,協調和管理多個并發任務的執行是一項重要的任務。Go語言提供了一個非常實用的并發原語——WaitGroup,它可以幫助我們優雅地實現并發控制。本文將介紹WaitGroup的基本用法,并重點討論其高級用法,通過具體的代碼示例來幫助讀者更好地理解和應用。
WaitGroup是Go語言內置的一個并發原語,它能夠幫助我們等待并發任務的完成。它提供了三個方法:Add、Done和Wait。Add方法用于設置等待任務的數量,Done方法用于減少等待任務的數量,Wait方法用于阻塞當前協程,直到所有等待任務完成。
下面是一個簡單的示例,展示了WaitGroup的基本用法:
package main import ( "fmt" "sync" "time" ) func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func(num int) { defer wg.Done() time.Sleep(time.Second) fmt.Println("Task", num, "done") }(i) } wg.Wait() fmt.Println("All tasks done") }
登錄后復制
在上面的代碼中,我們創建了一個WaitGroup對象wg,并通過循環創建了5個并發任務。在每個任務的執行過程中,我們使用Add方法增加等待任務的數量,并在任務結束時通過Done方法減少等待任務的數量。最后,我們調用Wait方法阻塞了主協程,直到所有等待任務完成。
除了基本的用法外,WaitGroup還提供了一些高級的用法,可以更加靈活地控制并發任務的執行。下面我們將詳細介紹幾個常用的高級用法。
- 執行一組任務并設置最大并發數
如果我們需要同時執行一組任務,但又希望限制最大并發數,可以使用帶緩沖通道結合WaitGroup來實現。下面的代碼展示了如何同時執行一組任務,但最多只允許3個任務并發執行:
package main import ( "fmt" "sync" "time" ) func main() { var wg sync.WaitGroup maxConcurrency := 3 tasks := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} sem := make(chan struct{}, maxConcurrency) for _, task := range tasks { wg.Add(1) sem <- struct{}{} // 獲取令牌,控制最大并發數 go func(num int) { defer wg.Done() time.Sleep(time.Second) fmt.Println("Task", num, "done") <-sem // 釋放令牌,允許新的任務執行 }(task) } wg.Wait() fmt.Println("All tasks done") }
登錄后復制
在上面的代碼中,我們創建了一個帶緩沖的通道sem,并將其大小設置為最大并發數。在每個任務開始前,我們通過sem <- struct{}{}語句獲取一個令牌,當任務完成后,使用<-sem語句釋放令牌。通過控制令牌的獲取和釋放,我們就能夠限制最大并發數。
- 超時控制并發任務的執行
有時候我們希望對并發任務的執行時間進行控制,并在超時時終止任務的執行。通過使用帶緩沖通道和定時器,我們可以輕松實現這個功能。下面的代碼展示了如何設置并發任務的超時時間為3秒:
package main import ( "fmt" "sync" "time" ) func main() { var wg sync.WaitGroup tasks := []int{1, 2, 3, 4, 5, 6, 7} timeout := 3 * time.Second done := make(chan struct{}) for _, task := range tasks { wg.Add(1) go func(num int) { defer wg.Done() // 模擬任務執行時間不定 time.Sleep(time.Duration(num) * time.Second) fmt.Println("Task", num, "done") // 判斷任務是否超時 select { case <-done: // 任務在超時前完成,正常退出 return default: // 任務超時,向通道發送信號 close(done) } }(task) } wg.Wait() fmt.Println("All tasks done") }
登錄后復制
在上面的代碼中,我們創建了一個通道done,并在任務執行過程中判斷通道是否關閉來判斷任務是否超時。當一個任務完成時,我們使用close(done)語句向done通道發送信號,表示任務已經超時。通過select語句選擇不同的分支來處理不同的情況。
通過上面的示例代碼,我們可以看到WaitGroup的高級用法在實際的并發編程中非常實用。掌握了這些技巧,我們能夠更好地控制并發任務的執行,提高代碼的性能和可維護性。希望讀者能通過本文的介紹和示例代碼,深入理解WaitGroup的用法,從而應用到實際的項目中。
以上就是并發編程技巧:Go WaitGroup的高級用法的詳細內容,更多請關注www.xfxf.net其它相關文章!