如何暂停并恢复goroutine?
我试着停下来,继续发牢骚。我知道我可以如何暂停并恢复goroutine?,go,concurrency,channel,goroutine,Go,Concurrency,Channel,Goroutine,我试着停下来,继续发牢骚。我知道我可以sleep跑步,但我要寻找的是一个“暂停/恢复”按钮,而不是计时器 这是我的尝试。我正在使用通道的阻塞功能暂停,并选择根据通道值切换要执行的内容。但是,在我的例子中,输出总是运行 func main() { ctx := wctx{} go func(ctx wctx) { for { time.Sleep(1 * time.Second) select {
sleep
跑步,但我要寻找的是一个“暂停/恢复”按钮,而不是计时器
这是我的尝试。我正在使用通道的阻塞功能暂停,并选择
根据通道值切换要执行的内容。但是,在我的例子中,输出总是运行
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{}
}
func main(){
ctx:=wctx{}
go func(ctx wctx){
为了{
时间。睡眠(1*时间。秒)
挑选{
case您需要初始化通道,记住从nil通道读取总是阻塞
使用默认值选择,
,案例从不阻塞
以下是您的程序的修改版本,修复了上述问题:
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{}
}
主程序包
进口(
“fmt”
“时间”
)
func main(){
ctx:=wctx{
暂停:make(chan struct{}),
简历:make(chan struct{}),
}
go func(ctx wctx){
为了{
挑选{
案例Aselect
具有多个就绪案例时,会伪随机选择一个。因此,如果goroutine在检查这些通道时“缓慢”,您可能会在pause
和resume
上发送一个值(假设它们已缓冲)因此,可以准备好从两个通道接收,并且可以首先选择resume
,然后在以后的迭代中,当goroutine不再暂停时,选择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)
输出(在上尝试):
暂停和恢复goroutine只有一种方法,但此功能存在于运行时内。否则,您可以尝试双重锁定和双重解锁互斥锁。通常,您不想这样做。听起来像是XY问题。您能解释为什么我需要在此处按引用传递吗?我想我没有修改结构的任何值,所以我不需要到
Running
Running
Running
Paused
Paused
Paused
Running
Running