我有一個簡單的 go 應用程式,它從標準輸入讀取并回顯文本。
如果輸入是start我啟動一個 goroutine,它將一些遞增的數字輸出到標準輸出。
我希望能夠停止,暫停這個 goroutine 的運行。我創建了一個發送信號的通道,但由于某種原因它一直在運行并且不會退出。
我猜選擇中的默認情況會繼續運行并且不會回傳?
我怎樣才能解決這個問題?
package main
import (
"bufio"
"fmt"
"os"
"strings"
"time"
)
func main() {
fmt.Println("starting...")
reader := bufio.NewReader(os.Stdin)
quit := make(chan bool)
for {
text, _ := reader.ReadString('\n')
text = strings.Replace(text, "\n", "", -1)
fmt.Printf("entered: %s\n", text)
switch {
case text == "start":
fmt.Println("starting")
go counter(1, 1, quit)
case text == "pause":
fmt.Println("pausing")
case text == "resume":
fmt.Println("resuming")
case text == "stop":
fmt.Println("stopping")
quit <- true
}
}
}
func counter(startFrom int, multiplyBy int, ch <-chan bool) {
for {
select {
case <-ch:
return
default:
for x := startFrom; x < 100; x {
time.Sleep(time.Millisecond * 1000)
result := x * multiplyBy
fmt.Printf("%d", result)
}
}
}
}
uj5u.com熱心網友回復:
你猜對了。一旦你的程式到達default分支,它不會嘗試接收,ch直到內部for退出。
解決方案是ch每次更新計數器時進行檢查。這是我修改后的counter()功能:
func counter(startFrom int, multiplyBy int, ch <-chan bool) {
for {
for x := startFrom; x < 100; x {
time.Sleep(time.Millisecond * 1000)
select {
case <-ch:
return
default:
result := x * multiplyBy
fmt.Printf("%d", result)
}
}
}
}
請注意select指令是如何嵌套在內部回圈而不是外部回圈中的。
PS 還有一點需要指出的是,雖然您的代碼可以在 Linux 或 Mac 上運行,但由于行尾不同,它不能在 Windows 上運行。你會得到text=="start\r"而不是text=="start"在 Windows 上。一個簡單的解決方案是text = strings.TrimSpace(text)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/514609.html
標籤:去
