为了账号安全,请及时绑定邮箱和手机立即绑定

在忽略 CTRL-C 的同时读取用户的输入

在忽略 CTRL-C 的同时读取用户的输入

Go
慕娘9325324 2022-01-04 13:33:36
我想在 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 干净地退出。


查看完整回答
反对 回复 2022-01-04
  • 1 回答
  • 0 关注
  • 171 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号