1 回答
TA贡献1794条经验 获得超7个赞
我认为可以通过在单个共享通道上进行选择,然后在完成后让服务器关闭它来完成您想要的操作。
假设我们创建了一个全局“退出通道”,它在所有 goroutine 之间共享。它可以在创建“服务器”goroutine 之前创建。重要的部分是服务器 goroutine 从不向通道发送任何内容,而只是将其关闭。
现在客户端 goroutines,只需执行以下操作:
select {
case <- ch:
fmt.Println("Channel closed, server is done!")
case <-time.After(time.Second):
fmt.Println("Timed out. do recovery stuff")
}
服务器 goroutine 只做:
close(ch)
更完整的例子:
package main
import(
"fmt"
"time"
)
func waiter(ch chan struct{}) {
fmt.Println("Doing stuff")
fmt.Println("Waiting...")
select {
case <- ch:
fmt.Println("Channel closed")
case <-time.After(time.Second):
fmt.Println("Timed out. do recovery stuff")
}
}
func main(){
ch := make(chan struct{})
go waiter(ch)
go waiter(ch)
time.Sleep(100*time.Millisecond)
fmt.Println("Closing channel")
close(ch)
time.Sleep(time.Second)
}
这可以抽象为以下实用程序 API:
type TimedCondition struct {
ch chan struct{}
}
func NewTimedCondition()*TimedCondition {
return &TimedCondition {
ch: make(chan struct{}),
}
}
func (c *TimedCondition)Broadcast() {
close(c.ch)
}
func (c *TimedCondition)Wait(t time.Duration) error {
select {
// channel closed, meaning broadcast was called
case <- c.ch:
return nil
case <-time.After(t):
return errors.New("Time out")
}
}
- 1 回答
- 0 关注
- 158 浏览
添加回答
举报