A select
с несколькими готовыми кейсами выбирает один псевдослучайно. Таким образом, если программа «медленно» проверяет эти каналы, вы можете отправить значение как на pause
, так и на resume
(при условии, что они буферизированы), так что прием от обоих каналов может быть готов, и сначала можно выбрать resume
и на более поздней итерации pause
, когда выполнение программы больше не должно приостанавливаться.
Для этого вы должны использовать переменную "state", синхронизированную мьютексом. Примерно так:
const (
StateRunning = iota
StatePaused
)
type wctx struct {
mu sync.Mutex
state int
}
func (w *wctx) SetState(state int) {
w.mu.Lock()
defer w.mu.Unlock()
w.state = state
}
func (w *wctx) State() int {
w.mu.Lock()
defer w.mu.Unlock()
return w.state
}
Тестирование:
ctx := &wctx{}
go func(ctx *wctx) {
for {
time.Sleep(1 * time.Millisecond)
switch state := ctx.State(); state {
case StatePaused:
fmt.Println("Paused")
default:
fmt.Println("Running")
}
}
}(ctx)
time.Sleep(3 * time.Millisecond)
ctx.SetState(StatePaused)
time.Sleep(3 * time.Millisecond)
ctx.SetState(StateRunning)
time.Sleep(2 * time.Millisecond)
Вывод (попробуйте на Go Детская площадка ):
Running
Running
Running
Paused
Paused
Paused
Running
Running