Joh*_*ass 0 concurrency channel go goroutine
我正在尝试暂停和恢复 groutine。我知道我可以sleep跑步,但我正在寻找就像一个按钮“暂停/恢复”而不是一个计时器。
这是我的尝试。我正在使用通道的阻塞功能来暂停,并select根据通道值切换要执行的内容。但是,输出总是Running在我的情况下。
func main() {
ctx := wctx{}
go func(ctx wctx) {
for {
time.Sleep(1 * time.Second)
select {
case <-ctx.pause:
fmt.Print("Paused")
<-ctx.pause
case <-ctx.resume:
fmt.Print("Resumed")
default:
fmt.Print("Running \n")
}
}
}(ctx)
ctx.pause <- struct{}{}
ctx.resume <- struct{}{}
}
type wctx struct {
pause chan struct{}
resume chan struct{}
}
Run Code Online (Sandbox Code Playgroud)
select具有多个就绪案例的A伪随机地选择一个。因此,如果 goroutine 检查这些通道很“慢”,您可能会在两个pause和resume(假设它们已缓冲)上发送一个值,以便从两个通道接收可以准备好,并且resume可以首先选择,并在以后的迭代pause中goroutine 不应再暂停。
为此,您应该使用由互斥锁同步的“状态”变量。像这样的东西:
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
}
Run Code Online (Sandbox Code Playgroud)
测试它:
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)
Run Code Online (Sandbox Code Playgroud)
输出(在Go Playground上试试):
Running
Running
Running
Paused
Paused
Paused
Running
Running
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
333 次 |
| 最近记录: |