How to send an interrupt signal

huangapple go评论85阅读模式
英文:

How to send an interrupt signal

问题

我正在尝试实现一个在Go中调用中断信号的函数。我知道如何通过使用signal.Notify(interruptChannel, os.Interrupt)来拦截来自控制台的中断信号,但是我找不到一种实际发送中断信号的方法。我发现你可以向进程发送信号,但我不确定是否可以用来发送顶层中断信号。

在Go中是否有一种方法可以从函数内部发送中断信号,以便可以被监听系统中断信号的任何东西捕获,或者这在Go中不支持?

英文:

I'm trying to implement a function that would call an interrupt signal in Go. I know how to intercept interrupt signals from the console, by using signal.Notify(interruptChannel, os.Interrupt), however, I can't find a way to actually send the interrupt signals around. I've found that you can send a signal to a process, but I'm not sure if this can be used to send a top-level interrupt signal.

Is there a way to send an interrupt signal from within a Go function that could be captured by anything that is listening for system interrupt signals, or is that something that's not supported in Go?

答案1

得分: 70

假设你正在使用以下代码来捕获中断信号:

var stopChan = make(chan os.Signal, 2)
signal.Notify(stopChan, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)

<-stopChan // 等待 SIGINT

在你的代码的任何地方,可以使用以下方法发送中断信号给上述等待部分:

syscall.Kill(syscall.Getpid(), syscall.SIGINT)

或者,如果你在与 stopChan 变量定义在同一个包中,可以这样做,使其可访问:

stopChan <- syscall.SIGINT

或者,你可以将 stopChan 定义为全局变量(将首字母大写也可以实现相同效果),这样你可以从不同的包发送中断信号:

StopChan <- syscall.SIGINT
英文:

Assuming you are using something like this for capturing interrupt signal

var stopChan = make(chan os.Signal, 2)
signal.Notify(stopChan, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)

&lt;-stopChan // wait for SIGINT

Use below from anywhere in your code to send interrupt signal to above wait part.

syscall.Kill(syscall.Getpid(), syscall.SIGINT)

Or if you are in the same package where where stopChan variable is defined. Thus making it accessible. You can do this.

stopChan &lt;- syscall.SIGINT

Or you can define stopChan as a global variable (making the first letter in Capital letter will achieve the same), then you can send interrupt signal from a different package too.

Stopchan &lt;- syscall.SIGINT

答案2

得分: 20

使用FindProcessStartProcess或其他方法获取进程。调用Signal发送中断信号:

err := p.Signal(os.Interrupt)

这将向目标进程发送信号(假设调用进程有权限这样做),并调用目标进程可能为SIGINT设置的任何信号处理程序。

英文:

Get the process using FindProcess, StartProcess or some other means. Call Signal to send the interrupt:

 err := p.Signal(os.Interrupt)

This will send the signal to the target process (assuming the calling process has permission to do so) and invoke whatever signal handlers the target process may have for SIGINT.

答案3

得分: 1

对于Windows系统,您可以使用以下方法:

func SendInterrupt() error {
	d, e := syscall.LoadDLL("kernel32.dll")
	if e != nil {
		return fmt.Errorf("LoadDLL: %v", e)
	}
	p, e := d.FindProc("GenerateConsoleCtrlEvent")
	if e != nil {
		return fmt.Errorf("FindProc: %v", e)
	}
	r, _, e := p.Call(syscall.CTRL_BREAK_EVENT, uintptr(syscall.Getpid()))
	if r == 0 {
		return fmt.Errorf("GenerateConsoleCtrlEvent: %v", e)
	}
	return nil
}

希望对您有帮助!

英文:

For the windows case you may use the following method:

func SendInterrupt() error {
	d, e := syscall.LoadDLL(&quot;kernel32.dll&quot;)
	if e != nil {
		return fmt.Errorf(&quot;LoadDLL: %v&quot;, e)
	}
	p, e := d.FindProc(&quot;GenerateConsoleCtrlEvent&quot;)
	if e != nil {
		return fmt.Errorf(&quot;FindProc: %v&quot;, e)
	}
	r, _, e := p.Call(syscall.CTRL_BREAK_EVENT, uintptr(syscall.Getpid()))
	if r == 0 {
		return fmt.Errorf(&quot;GenerateConsoleCtrlEvent: %v&quot;, e)
	}
	return nil
}

huangapple
  • 本文由 发表于 2016年11月9日 07:51:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/40498371.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定