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

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

在 Go 中以一定間隔同時運行多個函數

在 Go 中以一定間隔同時運行多個函數

Go
呼如林 2023-04-04 17:03:12
我有一個函數列表和它們各自的間隔。我想同時運行每個函數的時間間隔。在 JavaScript 中,我寫了類似這樣的東西:maps.forEach(({fn, interval}) => {     setInterval(fn, interval) })我如何在 Golang 中實現此功能?
查看完整描述

1 回答

?
波斯汪

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

使用 atime.Ticker定期接收“事件”,您可以使用它來為函數的執行計時。time.Ticker您可以通過致電獲得time.NewTicker()。返回的代碼有一個定期發送值的通道。

使用 goroutine 連續接收事件并調用函數,例如使用循環for range。

讓我們看看 2 個函數:

func oneSec() {

? ? log.Println("oneSec")

}


func twoSec() {

? ? log.Println("twoSec")

}

這是一個定期調用給定函數的簡單調度程序:


func schedule(f func(), interval time.Duration) *time.Ticker {

? ? ticker := time.NewTicker(interval)

? ? go func() {

? ? ? ? for range ticker.C {

? ? ? ? ? ? f()

? ? ? ? }

? ? }()

? ? return ticker

}

使用它的例子:


func main() {

? ? t1 := schedule(oneSec, time.Second)

? ? t2 := schedule(twoSec, 2*time.Second)

? ? time.Sleep(5 * time.Second)

? ? t1.Stop()

? ? t2.Stop()

}

示例輸出(在Go Playground上嘗試):


2009/11/10 23:00:01 oneSec

2009/11/10 23:00:02 twoSec

2009/11/10 23:00:02 oneSec

2009/11/10 23:00:03 oneSec

2009/11/10 23:00:04 twoSec

2009/11/10 23:00:04 oneSec

請注意,Ticker.Stop()不會關閉代碼通道,因此 afor range不會終止;Stop()僅停止在代碼通道上發送值。


如果您想終止用于安排函數調用的 goroutine,您可以使用額外的通道來完成。然后那些 goroutines 可能會使用一個select語句來“監控”ticker 的頻道和這個done頻道,如果從中接收done成功則返回。


例如:


func schedule(f func(), interval time.Duration, done <-chan bool) *time.Ticker {

? ? ticker := time.NewTicker(interval)

? ? go func() {

? ? ? ? for {

? ? ? ? ? ? select {

? ? ? ? ? ? case <-ticker.C:

? ? ? ? ? ? ? ? f()

? ? ? ? ? ? case <-done:

? ? ? ? ? ? ? ? return

? ? ? ? ? ? }

? ? ? ? }

? ? }()

? ? return ticker

}

并使用它:


func main() {

? ? done := make(chan bool)

? ? t1 := schedule(oneSec, time.Second, done)

? ? t2 := schedule(twoSec, 2*time.Second, done)

? ? time.Sleep(5 * time.Second)

? ? close(done)

? ? t1.Stop()

? ? t2.Stop()

}

請注意,即使在這個簡單的示例中沒有必要停止代碼(因為當maingoroutine 結束時,程序也會結束),在現實生活中,如果應用程序繼續運行,讓代碼不停止會浪費資源(它們會繼續使用后臺 goroutine,并將繼續嘗試在他們的頻道上發送值)。

最后的話:

如果您有一段函數區間對,只需使用循環將每一對傳遞給此schedule()函數即可。是這樣的:

type pair struct {

? ? f? ? ? ? func()

? ? interval time.Duration

}


pairs := []pair{

? ? {oneSec, time.Second},

? ? {twoSec, 2 * time.Second},

}


done := make(chan bool)

ts := make([]*time.Ticker, len(pairs))

for i, p := range pairs {

? ? ts[i] = schedule(p.f, p.interval, done)

}


time.Sleep(5 * time.Second)

close(done)


for _, t := range ts {

? ? t.Stop()

}


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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