亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將順序測試分散到 4 個 go 例程中,如果有一個失敗則終止所有測試

將順序測試分散到 4 個 go 例程中,如果有一個失敗則終止所有測試

Go
開心每一天1111 2021-11-15 17:04:52
假設我有一個簡單的循環,它執行這樣的順序測試。 for f := 1; f <= 1000; f++ {            if doTest(f) {              break            }  }我遍歷數字范圍并對每個數字進行測試。如果一個數字的測試失敗,我會中斷并退出主線程。足夠簡單。現在,如何正確地在四個或幾個 go 例程中輸入測試數字?;旧希蚁胍?4 為一組(或任何數量的 go 例程)測試從 1 到 1000 的數字。我是否創建 4 個從一個通道讀取的例程并將數字按順序輸入該通道?還是我用一個單獨的頻道做 4 個例程?還有一個問題。如果其中一個例程未通過測試,我如何停止所有 4 個例程?我一直在閱讀頻道上的一些文本,但我無法將這些片段放在一起。
查看完整描述

2 回答

?
皈依舞

TA貢獻1851條經驗 獲得超3個贊

您可以創建一個生產者/消費者系統:https : //play.golang.org/p/rks0gB3aDb


func main() {

    ch := make(chan int)

    clients := 4

    // make it buffered, so all clients can fail without hanging

    notifyCh := make(chan struct{}, clients)

    go produce(100, ch, notifyCh)


    var wg sync.WaitGroup

    wg.Add(clients)

    for i := 0; i < clients; i++ {

        go func() {

            consumer(ch, notifyCh)

            wg.Done()

        }()

    }

    wg.Wait()


}


func consumer(in chan int, notifyCh chan struct{}) {

    fmt.Printf("Start consumer\n")

    for i := range in {

        <-time.After(100 * time.Millisecond)

        if i == 42 {

            fmt.Printf("%d fails\n", i)

            notifyCh <- struct{}{}

            return

        } else {

            fmt.Printf("%d\n", i)

        }


    }

    fmt.Printf("Consumer stopped working\n")

}


func produce(N int, out chan int, notifyCh chan struct{}) {

    for i := 0; i < N; i++ {

        select {

        case out <- i:

        case <-notifyCh:

            close(out)

            return

        }

    }

    close(out)

}

生產者將數字從 0 到 99 推送到通道,消費者一直消費直到通道關閉。在 main 中,我們創建了 4 個客戶端并將它們添加到一個等待組中,以可靠地檢查每個 goroutine 是否返回。每個消費者都可以在 notifyCh 上發信號,生產者停止工作并且不再產生更多的數字,因此所有消費者都在他們當前的數字之后返回。


還有一個選項可以創建4個go例程,等待它們全部返回,開始接下來的4個go例程。但這會增加等待的開銷。


既然你提到了素數,這里有一個非??岬乃財担篽ttps ://golang.org/doc/play/sieve.go


查看完整回答
反對 回復 2021-11-15
?
LEATH

TA貢獻1936條經驗 獲得超7個贊

您是要為每個例程創建一個公共頻道還是一個頻道,取決于您想要什么。

如果你只想在里面放一些數字(或更一般的 - 請求)并且你不關心哪個 goroutine 提供服務,那么當然最好共享一個頻道。例如,如果您希望 goroutine1 為前 250 個請求提供服務,那么您當然不能共享頻道。

對于通道是一個很好的做法,將其用作輸入或輸出。發送者如何發送最簡單的事情,他完成了關閉通道。關于這一點的好文章是https://blog.golang.org/pipelines

問題中沒有提到的是 - 您是否還需要另一個通道(或多個通道)或任何其他通信原語來獲得結果。這是比喂食更有趣的渠道。

應該發送什么信息 - 應該發送它,在每次 doTest 之后發送一個 bool,或者只知道什么時候完成了所有事情(在這種情況下,bool 都不需要只關閉一個通道)?

如果你喜歡程序一開始就失敗。比我更喜歡使用緩沖共享通道來提供數字。不要忘記關閉它,當所有數字都將被饋送時。

另一個無緩沖的 chan 讓主線程知道,測試已經完成。它可以是通道,在那里你只輸入數字,測試失敗的地方,或者如果你還想要一個肯定的結果 - 包含數字和結果的結構通道,或從 doTest 返回的任何其他信息。

關于頻道的非常好的文章也是http://dave.cheney.net/2014/03/19/channel-axioms

您的四個 goroutine 中的每一個都可以報告失?。ㄍㄟ^發送錯誤和關閉通道)。但是當所有數字都通過并且饋送通道關閉時,goroutines 應該做的是gotcha。關于那也是不錯的文章http://nathanleclaire.com/blog/2014/02/15/how-to-wait-for-all-goroutines-to-finish-executing-before-continuing/


查看完整回答
反對 回復 2021-11-15
  • 2 回答
  • 0 關注
  • 210 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號