在 Go 中,我有两个最终不会触发的回调。
registerCb(func() {...})
registerCb(func() {...})
/* Wait for both func to execute with timeout */
我想等待它们,但如果其中一个没有执行,则会超时。
同步。WaitGroup 不起作用,因为它是阻塞的,而不是基于通道的。此外,您调用 WaitGroup.Done() 而不会在回调之外出现恐慌的风险。
我目前的解决方案是只使用两个布尔值和一个繁忙的等待循环。但这并不令人满意。是否有任何不使用轮询或忙碌等待的惯用方法?
更新:
下面是一些代码,演示了一个繁忙的等待解决方案,但应该在两个回调都触发后立即返回,或者在超时之后返回,而不使用轮询
package main
import (
"fmt"
"log"
"sync"
"time"
)
var cbOne func()
var cbTwo func()
func registerCbOne(cb func()) {
cbOne = cb
}
func registerCbTwo(cb func()) {
cbTwo = cb
}
func executeCallbacks() {
<-time.After(1 * time.Second)
cbOne()
// Might never happen
//<-time.After(1 * time.Second)
//cbTwo()
}
func main() {
// Some process in background will execute our callbacks
go func() {
executeCallbacks()
}()
err := WaitAllOrTimeout(3 * time.Second)
if err != nil {
fmt.Println("Error: ", err.Error())
}
fmt.Println("Hello, playground")
}
func WaitAllOrTimeout(to time.Duration) error {
cbOneDoneCh := make(chan bool, 1)
cbTwoDoneCh := make(chan bool, 1)
cbOneDone := false
cbTwoDone := false
registerCbOne(func() {
fmt.Println("cb One");
cbOneDoneCh <- true
})
registerCbTwo(func() {
fmt.Println("cb Two");
cbTwoDoneCh <- true
})
// Wait for cbOne and cbTwo to be executed or a timeout
// Busywait solution
for {
select {
case <-time.After(to):
if cbOneDone && cbTwoDone {
fmt.Println("Both CB executed (we could poll more often)")
return nil
}
fmt.Println("Timeout!")
return fmt.Errorf("Timeout")
case <-cbOneDoneCh:
cbOneDone = true
case <-cbTwoDoneCh:
cbTwoDone = true
}
}
}
阿晨1998
饮歌长啸
撒科打诨
慕斯王
随时随地看视频慕课网APP
相关分类