我想在 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 关注
- 171 浏览
添加回答
举报
0/150
提交
取消