我试图制作一个使用信号来中断无限计数器循环的程序。我已设法用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:")
}
答案 0 :(得分:0)
然后我会坚持我的第一个评论。我会解释一下。
您不需要信号让您的程序终止 - 您可以控制它。随时调用os.Exit
将退出该程序,从main()
返回具有相同的效果。
问题是,何时触发这些&#34;退出&#34;。或者,在您的示例中,如何在按下key Q
时触发退出。
要解决此问题,您需要将其分解为多个部分。正如我在评论中所说,第1部分正在捕捉关键击球。它不像fmt.Scan
那么简单,因为它需要用户按下后输入。它需要一些特定于操作系统的代码来执行此操作,但希望lib可以为您节省所有麻烦,例如termbox-go。
第2部分与第1部分紧密相关。即指定事件,键击。在您的示例中,要知道按下的键是Q,然后调用os.Exit
。通常lib可以很容易地处理它,有时很难注意到有一部分。但是如果你想要一些更复杂的关键词,比如ctrl-alt-backspace
,甚至a-s-d-f
(同时),这将需要一些代码。
第三部分是关于不阻止该程序。在Go中,可以通过使用单独的goroutine来检查事件循环或使用旧的回调方式轻松实现。这取决于您选择的图书馆。
关于信号和ctrl-c
案例的更多信息。通常的做法是ctrl-c
必然会在大多数情况下向程序发送一个sigint。如果没有修改,sigint会终止程序。但是,程序可以修改处理sigint的行为,就像你的orignal代码那样(添加一条消息来打印)。当按下其他键时,操作系统不太可能将其绑定到另一个信号,因此您无法处理它。
另一个解决方案是将一个键组合(多个键击)绑定到向程序发送一个sigint,但只要该程序是接收键击本身的程序,那就是一个不情愿的。
注意:由于库的选择可以变化,因此代码差别很大,所以我认为我不能(或应该)提供一个例子。