【问题标题】:Interrupting an infinite loop in Golang with signals用信号中断 Golang 中的无限循环
【发布时间】:2018-07-17 03:14:28
【问题描述】:

我正在尝试制作一个使用信号中断无限计数器循环的程序。我已经设法用 SIGINT (ctrl + C) 中断了程序,但我无法以其他方式中断它。我想知道是否可以通过其他方式中断循环,例如在终端中运行时按 Q 键。

我制作了两个 Go 文件,第一个包含实际的无限循环:

package infinite

import "fmt"
import "time"

func Infinite01 (msg string) {
for i := 0; ; i++ {
    fmt.Println(msg, i)
    time.Sleep(time.Second)
    }
}

然后文件捕获SIGINT信号并中断循环:

package main

import (
"./infinite"
"os/signal"
"os"
"fmt"
)

func main() {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, os.Interrupt)
go func() {
    <-sigs
    fmt.Printf("You pressed ctrl + C. User interrupted infinite loop.")
    os.Exit(0)
}()
Loop()
}

func Loop() {
infinite.Infinite01("Look, I can count forever:")
}

【问题讨论】:

  • 您想要实现的只是1)在终端中捕获击键 2)当捕获到指定的击键时,退出程序 3)整个过程不会阻塞程序,因此它可以运行其他代码(如无限循环)。第三部分实际上是用 goroutine 完成的,所以只剩下两个了。而且我相信在 Google 上搜索它们都会产生有用的结果。
  • @leafbebop 说 OP 想要用户输入,这将是显而易见的解决方案。
  • @Remario 你会说 OP 想要什么?
  • 据我所知,“按 Q 键”并没有发送信号,也没有发送任何其他信息。
  • 我知道我在这里可能用词不当。除了 Ctrl + C 之外,我想要做的是创建一个中断信号,它可以用于同一件事(中断正在运行的无限循环进程)。那可能吗?如果是这样,我会怎么做?感谢您的快速回复!

标签: loops for-loop go signals sigint


【解决方案1】:

然后我会坚持我的第一条评论。我再解释一下。

你不需要一个信号来终止你的程序——你可以控制它。任何时候调用os.Exit都会退出程序,从main()返回也一样。

相反,问题在于何时触发这些“退出”。或者,在您的示例中,如何在按下key Q 时触发退出。

要解决问题,您需要将其分解为多个部分。正如我在 cmets 中所说,第 1 部分是捕捉击键。它不像fmt.Scan 那样简单,因为它需要用户在它之后按下回车。它需要一些特定于操作系统的代码来执行此操作,但希望 lib 可以为您省去所有麻烦,例如 termbox-go

第 2 部分与第 1 部分紧密相关。即指定事件,即击键。在您的示例中,要知道按下的键是 Q,然后调用 os.Exit。通常一个库可以很容易地处理这个问题,有时几乎没有注意到有一部分。但是如果你想要一些更复杂的按键,比如ctrl-alt-backspace,甚至a-s-d-f(同时),这将需要一些代码。

第三部分是关于不阻塞程序。在 Go 中,可以很容易地通过使用单独的 goroutine 来检查事件循环,或者使用古老的回调方式来实现。这取决于您选择的图书馆。

关于信号和ctrl-c 案例的更多信息。在大多数情况下,ctrl-c 必然会向程序发送信号是常见的做法。如果没有修改,sigint 会终止程序。但是,程序可以修改处理 sigint 的行为,就像您的原始代码一样(添加要打印的消息)。当按下其他键时,操作系统不太可能将其绑定到另一个信号,因此您无法处理。

当然,另一种解决方案是将按键组合(多个按键)绑定到向程序发送信号,但只要程序是接收按键本身的程序,那就是冗余。

注意:由于库的选择是多种多样的,所以代码差异很大,所以我认为我不能(或不应该)提供示例。

【讨论】:

  • 感谢您的精彩回复!这给我留下了一些选择。我会检查出来的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-08
  • 2012-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多