![](/img/trans.png)
[英]Is there some elegant way to pause and resume any other goroutine?
[英]How to pause and resume 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{}
}
一個select
多准備的情況下選擇一個偽隨機。 因此,如果 goroutine 檢查這些通道很“慢”,您可能會在pause
和resume
發送一個值(假設它們已緩沖),以便從兩個通道接收可以准備好,並且可以首先選擇resume
,然后在以后的迭代中goroutine 不應再pause
時的暫停。
為此,您應該使用由互斥鎖同步的“狀態”變量。 像這樣的東西:
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 Playground上試試):
Running
Running
Running
Paused
Paused
Paused
Running
Running
你需要初始化你的通道,記住從 nil 通道讀取總是阻塞的。
default
情況下的select
永遠不會阻塞。
這是您的程序的修改版本,它解決了上述問題:
package main
import (
"fmt"
"time"
)
func main() {
ctx := wctx{
pause: make(chan struct{}),
resume: make(chan struct{}),
}
go func(ctx wctx) {
for {
select {
case <-ctx.pause:
fmt.Println("Paused")
case <-ctx.resume:
fmt.Println("Resumed")
}
fmt.Println("Running")
time.Sleep(time.Second)
}
}(ctx)
ctx.pause <- struct{}{}
ctx.resume <- struct{}{}
}
type wctx struct {
pause chan struct{}
resume chan struct{}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.