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

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

在 Go 中定期調用 N 個并發函數的最佳方法是什么?

在 Go 中定期調用 N 個并發函數的最佳方法是什么?

Go
拉風的咖菲貓 2023-06-26 15:33:16
在過去的一天左右的時間里,我一直在努力解決一個問題,尋找創建 N 個并發函數的最佳方法,這些函數在 Go 中以相同的時間間隔定期調用。我希望能夠指定任意數量的函數,讓它們全部同時定期運行,并在指定的時間后結束它們。現在我有一個可行的解決方案,但必須為每個并發函數創建一個新的代碼。我也不確定如何正確使用sync.WaitGroup,因為我當前的實現導致程序永遠不會結束(最后卡在 wg.Wait() 上)func main() {? ? N := 10? ? var wg sync.WaitGroup? ? wg.Add(N)? ? quit := make(chan struct{})? ? for i := 0; i < N; i++ {? ? ? ? tick := time.NewTicker(500 * time.Millisecond)? ? ? ? go func(t *time.Ticker) {? ? ? ? ? ? for a := range tick.C {? ? ? ? ? ? ? ? select {? ? ? ? ? ? ? ? case <-quit:? ? ? ? ? ? ? ? ? ? break? ? ? ? ? ? ? ? default:? ? ? ? ? ? ? ? ? ? fmt.Println(a) // do something on tick? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? ? ? wg.Done()? ? ? ? }(tick)? ? }? ? time.Sleep(10 * time.Second)? ? close(quit)? ? wg.Wait()}Go Playground 演示所以這個解決方案有效,以適當的時間間隔同時執行所有的代碼并在 10 秒后完成,但它實際上并沒有退出程序,而是掛在最后的 wg.Wait() 行上。此外,每個并發函數調用都使用自己的代碼 - 有什么方法可以讓所有函數都可以使用一個&ldquo;主&rdquo;代碼?提前致謝!這是我第一次真正深入研究 Go 的并發性。
查看完整描述

1 回答

?
波斯汪

TA貢獻1811條經驗 獲得超4個贊

你的程序永遠不會退出的原因是 Go 語言的一個奇怪的怪癖:breakfor 語句case <-quit退出select語句,而不是循環。(不知道為什么這種行為會有用。)要修復你的程序,你需要顯式地打破循環:


tickLoop:

    for a := range tick.C {

        select {

        case <-quit:

            break tickLoop

        default:

            fmt.Println(a, "function #", id) // do something on tick

        }

    }

在編寫代碼時,它總是等到下一個時鐘周期才退出。tick.C您也可以通過讀取 select 語句來解決此問題:


tickLoop:

    for {

        select {

        case <-quit:

            break tickLoop

        case a := <-tick.C:

            fmt.Println(a, "function #", id) // do something on tick

        }

    }

最后,如果您想重組程序以僅使用一個股票代碼,您可以啟動一個額外的 goroutine,它監聽股票代碼和通道quit,然后N在每個股票代碼時啟動子 goroutine。


查看完整回答
反對 回復 2023-06-26
  • 1 回答
  • 0 關注
  • 132 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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