dongyan9950 2018-02-06 23:15
浏览 138
已采纳

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

I'm trying to make a program that uses signals to interrupt an infinite counter loop. I've managed to interrupt the program with SIGINT (ctrl + C), but I'm unable to interrupt it otherwise. I'm wondering if I can make other ways of interrupting the loop, for example by pressing the Q key while it is running in the terminal.

I've made two Go-files, the first one containing the actual infinite loop:

package infinite

import "fmt"
import "time"

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

And then the file to catch the SIGINT signal and interrupt the loop:

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条回答 默认 最新

  • doujiao3346 2018-02-07 01:06
    关注

    Then I would stick to my first comment. I would explain a little more.

    You don't need a signal to have your program terminate - you have control over it. Call os.Exit at any time would exit the program, and return from main() has the same effect.

    The problem is, instead, that when to trigger these "exits". Or, in your example, how to trigger the exit when the key Q is pressed.

    To solve the problem, you need to break it down into parts. As I said in the comments, the part 1 is capturing the key stroke. It is not as simple as an fmt.Scan, as it would require the user press an enter after it. It requires some os specific code to do so, but hopefully a lib can save you all the trouble, like termbox-go.

    The part 2 is tightly associated with part 1. That is to specify the event, the key stroke. In your example, to know the key pressed is Q, and then call os.Exit. Usually a lib can handle that pretty easily, sometimes one can hardly notice there is a part. But if you want some more complicated key stokes, like ctrl-alt-backspace, or even a-s-d-f (at the same time), this will require some codes.

    The 3rd part is about not blocking the program. In Go, it can easily be acheived by using a seperate goroutine to check an event loop, or use the good-old callback way. It is up to library you pick.

    A little more about signal and the ctrl-c case. It is common practice that ctrl-c is bound to send a sigint to the program, in most situations. And if not modified, a sigint terminates a program. However, a program can modify the behavior of dealing with sigint, like your orignal code does (adds a message to print). When pressing other keys, it is unlikely the os would bind it to another signal, so you can not deal with it.

    Of corse another solution would be bind a key compostion (multiple key strokes) to sending a sigint to the program, but as long as the program is the program receiving the key stroke itself, that is a redunctant.

    Note: Because of the choice of libs can be varied, the codes are very much differed, so I don't think I can (or should) provide an example.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么