Golang 同步等待組 WaitGroup

2021-10-07 12:42:37 字數 2970 閱讀 9417

如果你正在學習go的高效能併發應用開發,那麼了解同步等待組至關重要。本文帶你認識同步等待組並通過示例進行說明。

讓我們直入主題,說明是同步等待組(waitgroup),能夠解決什麼問題。

在實際使用go協程實現並行應用時,可能會遇到這樣場景:需要阻塞部分**執行,直到其他協程成功執行之後才繼續執行。

示例**:

package main

import "fmt"

func myfunc()

func main()

程式首先列印"hello world",接著啟動協程,最後列印"finished execution"。

但我們執行程式結果並不是我們預期的結果,協程內的資訊"inside my goroutine"並沒有出現。這是因為main在協程執行之前以及結束,所以協程中的邏輯並未執行。

如何解決————同步等待組(waitgroups)

同步等待組(waitgroups)就是要解決這類問題,阻塞應用直到同步等待組中的所有協程都成功執行。

首先呼叫同步等待組的add(1)方法,設定需要等待協程數量, 然後再協程內部呼叫done()方法表明協程執行結束。

注意,需要確保再執行協程之前呼叫add(1)方法。

掌握了一些基本概念後,下面通過示例展示如何通過同步等待組解決上述問題:

package main

import (

"fmt"

"sync"

)func myfunc(waitgroup *sync.waitgroup)

func main()

我們看到首先例項化sync.waitgroup,然後再執行協程之前呼叫add(1)方法。修改原來函式增加*sync.waitgroup引數,並在函式內部成功完成任務後呼叫一次done方法。最後呼叫waitgroup.wait()方法阻塞main函式執行,直到同步等待組中的協程成功執行完成。

下面再次執行程式輸出結果如下:

hello world

inside my goroutine

finished execution

我們也可以使用匿名函式實現相同功能。對於協程內部業務不複雜,匿名函式會讓程式更簡潔:

package main

import (

"fmt"

"sync"

)func main() ()

waitgroup.wait()

fmt.println("finished execution")

}

輸出結果一樣。對於稍微複雜的邏輯,可能需要給匿名函式傳入引數,例如需要傳入url引數:

go func(url string) (url)
只是寫法有點差異,其他都差不多。

在示例生產應用程式中,任務是建立乙個api,該api與大量其他api互動,並將結果聚合到乙個響應中。每個api呼叫大約花費2-3秒時間來返回響應,由於需要呼叫的api數量太多,不可能同步地進行此操作。

為了實現該功能,需要使用協程非同步執行這些請求。

func main()然而當我開始使用這種策略時,我注意到我對任何api呼叫都在協程有機會完成填充結果之前返回。這時需要使用同步等待組重新實現該功能,通過使用waitgroup,我可以有效地修復這種異常行為,並且只在所有goroutines完成後返回結果。

func main()現在我們增加同步等待鎖,它將對所有url執行http get請求,一旦執行完畢返回給呼叫客戶端。輸出結果為:

homepage endpoint hit

200 ok

200 ok

200 ok

returning response

處理這類問題的方法不止一種,通過使用golang的通道也可以實現類似功能。

本文學習了什麼是golang同步等待組以及如何使用它實現高效能應用。

等待程序結束wait

include include pid t wait int status status 子程序結束時返回的終止狀態 子程序是怎麼結束的 status是乙個傳出引數 如果父程序不關心子程序的狀態,向wait中傳入null 功能 等待子程序結束 阻塞等待 成功 返回子程序的pid,失敗 返回 1擴充套...

程序的等待 wait函式

wait函式 include include pid t wait int status 功能 等待子程序終止,如果子程序終止了,此函式會 子程序的資源。呼叫wait函式的程序會掛起,直到它的乙個子程序退出或收到乙個不能被忽視的訊號時才被喚醒。若呼叫程序沒有子程序或它的子程序已經結束,該函式立即返回...

程序的等待(wait和waitpid)

1.程序的等待 wait函式或waitpid程序可能發生如下情況 1 如果所有的子程序孩子執行,則阻塞 block 2 如果乙個子程序已經終止,正等待父程序獲取其終止狀態,則取得孩子程序的終止狀態返回 3 如果她沒有任何子程序,則立即出錯返回 函式的原型 include pid t wait int...