1 回答

TA貢獻1862條經驗 獲得超7個贊
您的實現與 Go 中的計劃作業/任務非常相似。有一些類似 cron 的庫可以讓您更好地控制任務,但在大多數情況下,帶有循環的簡單 goroutine 就足夠了。
以下是根據您的需求增加復雜性的更多示例:
永遠運行一個任務,每次運行之間等待 5 秒。無法停止并且不考慮任務的運行時間。這是最簡單的形式,也是最常見的形式。
go func() {
for {
task()
<-time.After(5 * time.Second)
}
}()
與以前相同,只是現在有一個通道可以在我們想要的時候停止任務。雖然您的實現允許您通過該方法停止任務Stop(),但 goroutine 將保持打開狀態,因為通道永遠不會關閉(因此會泄漏內存)。
// Includes a channel to stop the task if needed.
quit := make(chan bool, 1)
go func() {
task()
for {
select {
case <-quit:
return
case <-time.After(5 * time.Second):
task()
}
}
}()
// To stop the task
quit <- true
這是三個解決方案中最強大的解決方案。任務可以隨時停止,并且它還會考慮任務在等待再次運行時所花費的時間。在前面的示例中,如果任務運行時間為 1 秒,而您又等待 5 秒,則相對于任務啟動時的時間間隔實際上是 6 秒。
該解決方案實際上僅適用于運行時間非常長的任務,或者如果您的任務以恒定的時間間隔運行至關重要。如果任務必須以恒定的時間間隔運行,那么您需要考慮到time.After()至少會等待您提供的持續時間的事實——如果 CPU 忙于其他進程/goroutines,它最終可能會等待稍長的時間。
// Calls `fn` and then waits so the total elapsed time is `interval`
func runAndWait(interval time.Duration, fn func()) {
earlier := time.Now()
fn()
diff := time.Now().Sub(earlier)
<-time.After(interval - diff)
}
quit := make(chan bool, 1)
go func() {
// The total time to run one iteration of the task
interval := 5 * time.Second
for {
select {
case <-quit:
return
default:
runAndWait(interval, task)
}
}
}()
- 1 回答
- 0 關注
- 129 瀏覽
添加回答
舉報