我想在 go 中讀取用戶輸入并忽略用戶通過捕獲來終止我的進程的嘗試CTRL-C.我旋轉一個 goroutine 來捕獲CTRL-C并寫入通道。在這個階段,我希望控制權返回到case <-intr主 goroutine 中,但這并沒有發生。這是運行的輸出:$ go run read.go Enter text: helloEntered:hello$go run read.go Enter text: ^CGot signal interruptExiting signal handler..Invalid input2Interrupted.. ContinuingEnter text: ^CInvalid input2Enter text: ^CInvalid input2Enter text: ^C^C^C^CInvalid input2Enter text: ^CInvalid input2Enter text: ^CInvalid input2Enter text: 第一個 CTRL-C 被困住了,它退出后不久,似乎主 goroutine 正在執行 r := bufio.NewReader(os.Stdin)當我稍后按 CTRL-C 作為輸入時,它被簡單地視為文本并且不會調用信號處理程序。我的代碼如下(goplay 鏈接:http ://play.golang.org/p/LiKZMYGr00 )package mainimport ("fmt" "bufio" "os" "os/signal" "syscall" "io" "strings")func main() { c := make(chan os.Signal) intr := make(chan bool) signal.Notify(c, syscall.SIGINT) go func() { s := <-c fmt.Println("Got signal", s) fmt.Println("Exiting signal handler..") intr <- true return }()breakOutOfHere: for { select { case <-intr: fmt.Println("Interrupted.. Continuing") continue default: fmt.Printf("Enter text: ") r := bufio.NewReader(os.Stdin) text, ret := r.ReadString('\n') if ret == io.EOF { fmt.Println("Invalid input1") continue } else if ret == nil { text = strings.TrimSpace(text) if text == "" { fmt.Println("Invalid input2") continue } else { fmt.Printf("Entered:%s\n", text) break breakOutOfHere } } } }}
1 回答

茅侃侃
TA貢獻1842條經驗 獲得超22個贊
signal.Notify向指定的通道發送信號信息,每次進程收到信號。但是在您的代碼中,在第一個信號之后,go 例程完成。因此,它無法再次捕獲信號。
一種簡單的方法是,您需要在 go 例程中使用帶有 select 子句的無限循環。
go func(c chan os.Signal, quit chan bool) {
for {
select {
case <-c:
fmt.Println("Got interrupt signal")
fmt.Println("Exiting signal handler..")
intr <- true
case <-quit:
fmt.Println("quit")
return
}
}
}(c, quit)
在這里,使用 Channelquit來請求 go-routine 干凈地退出。
- 1 回答
- 0 關注
- 167 瀏覽
添加回答
舉報
0/150
提交
取消