Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 用信号中断Golang的无限循环_Loops_For Loop_Go_Signals_Sigint - Fatal编程技术网

Loops 用信号中断Golang的无限循环

Loops 用信号中断Golang的无限循环,loops,for-loop,go,signals,sigint,Loops,For Loop,Go,Signals,Sigint,我正试图制作一个程序,用信号来中断一个无限的计数器循环。我已经成功地用SIGINT(ctrl+C)中断了程序,但是我无法以其他方式中断它。我想知道我是否可以通过其他方式中断循环,例如在终端中运行时按Q键 我制作了两个Go文件,第一个包含实际的无限循环: package infinite import "fmt" import "time" func Infinite01 (msg string) { for i := 0; ; i++ { fmt.Println(msg, i)

我正试图制作一个程序,用信号来中断一个无限的计数器循环。我已经成功地用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:")
}
主程序包
进口(
“/无限”
“操作系统/信号”
“操作系统”
“fmt”
)
func main(){
信号:=接通(切换操作信号,1)
信号通知(信号、操作系统中断)
go func(){

然后我会坚持我的第一条评论,我会再解释一点

程序终止不需要信号,您可以控制它。随时调用
os.Exit
将退出程序,从
main()返回
具有相同的效果

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

要解决这个问题,您需要将其分解为几个部分。正如我在评论中所说的,第1部分是捕获关键笔划。它不像
fmt.Scan那样简单,因为它需要用户在它之后按enter键。这需要一些特定于操作系统的代码来完成,但希望lib可以为您省去所有的麻烦,例如

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

第三部分是关于不阻塞程序。在Go中,可以通过使用单独的goroutine检查事件循环,或者使用良好的旧回调方式轻松实现。这取决于您选择的库

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

对于corse,另一种解决方案是绑定一个键组合(多个键击)以向程序发送sigint,但只要程序本身就是接收键击的程序,这就是redunconstant


注意:由于LIB的选择可能会有所不同,因此代码差异很大,因此我认为我不能(或应该)这样做提供一个示例。

您想要实现的只是1)在终端中捕获一个按键笔划2)当捕获指定的按键笔划时,退出程序3)整个过程不会阻止程序,因此它可以运行其他代码(如无限循环)。第三部分实际上是用goroutine完成的,所以只剩下两部分。我相信在Google上搜索这两部分会得到有用的结果。@leafbebop说OP需要用户输入,这是显而易见的解决方案。@Remario你认为OP想要什么?据我所知,“按Q键”不发送信号,也不发送任何东西,只是按一下键。我知道我在这里的措辞可能很糟糕。我想做的是在Ctrl+C之外创建一个中断信号,可以用于相同的事情(中断正在运行的无限循环进程).有可能吗?如果有,我会怎么做?谢谢你的快速回复!谢谢你的回复!这给我留下了一些选择。我会看看的!