如何在Goroutine内部实现暂停与恢复处理?
实现Go控制台程序的暂停/恢复功能
要实现pause和resume命令,核心是通过通道传递不同的控制指令,并在goroutine内部维护运行状态。以下是改造后的完整代码,以及关键逻辑说明:
改造后的完整代码
package main import ( "bufio" "fmt" "os" "strings" "time" ) // 定义控制命令类型,统一管理所有控制指令 type Command string const ( CmdPause Command = "pause" CmdResume Command = "resume" CmdStop Command = "stop" ) func main() { fmt.Println("starting...") reader := bufio.NewReader(os.Stdin) // 用一个通道传递所有控制命令,替代原有的quit通道 cmdChan := make(chan Command) last := 1 isRunning := false // 标记计数器是否正在运行,避免重复启动 for { text, _ := reader.ReadString('\n') text = strings.TrimSpace(text) fmt.Printf("entered: %s\n", text) switch text { case "start": if !isRunning { fmt.Println("starting") isRunning = true go counter(last, 1, cmdChan, &last, &isRunning) } else { fmt.Println("counter is already running") } case "pause": if isRunning { fmt.Println("pausing") cmdChan <- CmdPause } else { fmt.Println("counter is not running") } case "resume": if isRunning { fmt.Println("resuming") cmdChan <- CmdResume } else { fmt.Println("counter is not running") } case "stop": if isRunning { fmt.Println("stopping") cmdChan <- CmdStop } } fmt.Printf("last is %v\n", last) } } func counter(startFrom int, multiplyBy int, cmdChan <-chan Command, last *int, isRunning *bool) { defer func() { *isRunning = false }() // goroutine退出时标记为未运行 paused := false x := startFrom for x < 100 { if !paused { time.Sleep(time.Millisecond * 1000) result := x * multiplyBy *last = result fmt.Printf("%d\n", result) x++ } // 监听控制命令,处理暂停/恢复/停止 select { case cmd := <-cmdChan: switch cmd { case CmdPause: paused = true fmt.Println("counter paused") case CmdResume: paused = false fmt.Println("counter resumed") case CmdStop: fmt.Println("counter stopped") return } default: // 如果没有命令且未暂停,继续循环;如果已暂停,阻塞等待命令 if paused { cmd := <-cmdChan switch cmd { case CmdResume: paused = false fmt.Println("counter resumed") case CmdStop: fmt.Println("counter stopped") return } } } } fmt.Println("counter finished naturally") }
关键逻辑说明
统一控制命令通道:
替换原有的quitbool通道,改用自定义Command类型的通道,能清晰区分暂停、恢复、停止三种指令,避免单一bool值的局限性。运行状态管理:
主函数中加入isRunning标志,防止重复启动多个计数器goroutine;计数器goroutine退出时通过defer将标志重置为false,保证状态同步。暂停/恢复的状态控制:
在counter函数内部维护paused变量,当收到暂停指令时设为true,此时不再执行计数逻辑,转而阻塞等待恢复或停止命令;收到恢复指令时将paused设为false,继续计数。避免空循环占用CPU:
暂停状态下,通过直接读取通道实现阻塞,避免无意义的空循环消耗CPU资源。
内容的提问来源于stack exchange,提问作者Blankman
相关产品推荐
相关产品推荐

