我遇到的问题是“发出所有正在等待的例程”。 在等待信号之前,一些例程可能正在执行其他任务(由time.Sleep在下面的代码中模拟)。其他人去常规可能会在启动后立即等待信号。在某些情况下,可能没有任何等待的例程(未在下面的代码中模拟)
我带来了以下方法:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
wg := sync.WaitGroup{}
wg.Add(3)
cond := sync.NewCond(&sync.Mutex{})
signalled := false
producer := func() {
time.Sleep(1)
cond.L.Lock()
signalled = true
cond.Broadcast()
cond.L.Unlock()
wg.Done()
}
go producer()
go func() {
time.Sleep(3 * time.Second)
cond.L.Lock()
for !signalled {
cond.Wait()
}
cond.L.Unlock()
wg.Done()
}()
go func() {
cond.L.Lock()
for !signalled {
cond.Wait()
}
cond.L.Unlock()
wg.Done()
}()
wg.Wait()
fmt.Println("done once")
reset := func() {
cond.L.Lock()
signalled = false
cond.L.Unlock()
}
// a reset function
reset()
wg.Add(2)
go producer()
go func() {
cond.L.Lock()
for !signalled {
cond.Wait()
}
cond.L.Unlock()
wg.Done()
}()
wg.Wait()
fmt.Println("done twice")
}
https://play.golang.org/p/uNmyofH2hs
我可以使用频道并关闭频道作为信号。但这意味着如果需要“重置”(可以再次触发“信号”),则必须再次创建频道。
是否有更好(简洁)的方法来实现这一目标?