В дополнение к ответу выше, если вы хотите отменить все официанты одновременно, вы можете инкапсулировать поведение, используя свой собственный механизм таймера, который можно отменить, который отправляет истину или ложь в канале After
, чтобы сообщить вам,просыпаются от отмены или перерыва для всех официантов.
package main
import (
"fmt"
"time"
)
type CancellableTimer struct {
cancel chan bool
}
func NewCancellableTimer() *CancellableTimer {
return &CancellableTimer{
cancel: make(chan bool),
}
}
// internal wait goroutine wrapping time.After
func (c *CancellableTimer) wait(d time.Duration, ch chan bool) {
select {
case <-time.After(d):
ch <- true
case <-c.cancel:
ch <- false
}
}
// After mimics time.After but returns bool to signify whether we timed out or cancelled
func (c *CancellableTimer) After(d time.Duration) chan bool {
ch := make(chan bool)
go c.wait(d, ch)
return ch
}
// Cancel makes all the waiters receive false
func (c *CancellableTimer) Cancel() {
close(c.cancel)
}
// a goroutine waiting for cancellation
func B(t *CancellableTimer) {
select {
// timedOut will signify a timeout or cancellation
case timedOut := <-t.After(time.Second):
if timedOut {
fmt.Println("Time out!")
} else {
fmt.Println("Cancelled!")
}
}
}
func main() {
t := NewCancellableTimer()
// Start 3 goroutines that wait for different timeouts on the same timer
go B(t)
go B(t)
go B(t)
// sleep a bit before cancelling
time.Sleep(100 * time.Millisecond)
// cancel the timer and all its waiters
t.Cancel()
// this is just to collect the output
time.Sleep(time.Second)
}
Выход:
Cancelled!
Cancelled!
Cancelled!
ссылка на игровую площадку:
https://play.golang.org/p/z8OscJCXTvD