gpt4 book ai didi

go - 忽略 CTRL-C 时读取用户输入

转载 作者:IT王子 更新时间:2023-10-29 02:29:42 32 4
gpt4 key购买 nike

我想在 go 中读取用户输入并忽略用户试图通过捕获 CTRL-C. 来终止我的进程。我旋转一个 goroutine 来捕获 CTRL-C并写入一个 channel 。在此阶段,我希望控制权返回到 case <-intr在主 goroutine 中,但这并没有发生。

这是运行的输出:

$ go run read.go 
Enter text: hello
Entered:hello

$go run read.go
Enter text: ^CGot signal interrupt
Exiting signal handler..

Invalid input2
Interrupted.. Continuing
Enter text: ^C
Invalid input2
Enter text: ^C
Invalid input2
Enter text: ^C^C^C^C
Invalid input2
Enter text: ^C
Invalid input2
Enter text: ^C
Invalid input2
Enter text:

第一个 CTRL-C 被困住了,在它退出后不久,主 goroutine 似乎正在执行 r := bufio.NewReader(os.Stdin)

当我稍后按 CTRL-C 作为输入时,它被简单地视为文本并且不会调用信号处理程序。

我的代码如下(goplay 链接:http://play.golang.org/p/LiKZMYGr00)

package main

import ("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
}
}
}
}
}

最佳答案

signal.Notify 发送信号信息到指定的 channel ,每次进程接收到信号。但是在你的代码中,例程在第一个信号之后完成。因此,它无法再次捕获信号。

一个简单的方法是,您需要在 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)

这里使用了 Channel quit,请求 go-routine 干净退出。

关于go - 忽略 CTRL-C 时读取用户输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36604177/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com