1 回答

TA貢獻1794條經驗 獲得超8個贊
我認為可以通過在單個共享通道上進行選擇,然后在完成后讓服務器關閉它來完成您想要的操作。
假設我們創建了一個全局“退出通道”,它在所有 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 關注
- 190 瀏覽
添加回答
舉報