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.

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

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?