簡體   English   中英

如何等待多個 goroutine 完成?

[英]How can wait for more than one goroutine to finish?

package main

var fooRunning = false
var barRunning = false

func foo() {
    fooRunning = true
    defer func() { fooRunning = false }()
    if barRunning {
        // wait for bar() to finish
    }
    ...
}

func bar() {
    barRunning = true
    defer func() { barRunning = false }()
    if fooRunning {
        // wait for foo() to finish
    }
    ...
}

在我的情況下,如果我們運行go foo()它應該等待bar()完成,反之亦然。 最好的方法是什么? 請注意,它們也可以獨立執行。

任何具體的設計都不能安全地滿足您的要求。 按照規定,你說foobar可以在並發 goroutines 中運行,並且如果它們中的一個或兩個已經啟動,另一個應該等待它們都完成。 不過,這太弱了。 如果foo開始然后將完成,但bar還沒有開始運行會發生什么? 如果bar根本不運行怎么辦? 或者如果bar運行,但foo從來沒有運行呢?

您是否要求foobar必須啟動並完成才能使您的程序正確? 如果是這樣,我可以猜測您打算開什么葯:您需要一個障礙,等待它們完成后再繼續。

package main

import (
    "fmt"
    "sync"
    "time"
)

func foo() {
    fmt.Println("foo")
}

func bar() {
    fmt.Println("bar")
}

func within(wg *sync.WaitGroup, f func()) {
    wg.Add(1)
    go func() {
        defer wg.Done()
        f()
    }()
}

func main() {
    var wg sync.WaitGroup
    within(&wg, foo)
    within(&wg, bar)
    wg.Wait()
    fmt.Println("Both foo and bar completed.")
}

Playground 中的相同示例

注意這里, foobar都不是相互感知的; 只有他們的調用者是,為了協調這兩個調用。

您最初的嘗試可能會讓您走上關閉foobar的道路,或者接受一個sync.WaitGroup作為參數,每個函數首先將自己添加到組中並在退出之前等待它 那就是瘋狂。

如果foobar有機會將自身添加到WaitGroup之前啟動並完成,則foo將在bar之前退出,即使您可以聲稱它們一直在同時運行,或者與barfoo注冊其活動狀態之前運行相反。 同樣,由於這是您的程序的一個指定不足的方面,我建議您將注意力集中在更高級別的障礙上,而不是這兩個函數的相互依賴上。

您可以使用頻道! 正如我從生銹的過程中記得的那樣,這將給出:

func foo() {
    c := make(chan int)
    go bar(c)
    <-c
}

在酒吧里

func bar(c chan int) {
    // do stuff here
    c <- 0
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM