如何在 Go 中捕获任意 UNIX 信号

我可以使用信号包捕获信号,但是如何捕获从 34(SIGRTMIN)到 64(SIGRTMAX)的信号(链接)?Golang 称它们为“信号 34”、“信号 64”等,但这已经超出了重点。当我运行“pkill -34”时,我希望我的应用程序注意到它。

当我捕获所有信号时,我可以捕获它们:

sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan)

但是我不想捕捉所有信号,我只想要我之前提到的那些。

我也知道我可以捕获单个信号,例如:

signal.Notify(sigChan, os.Interrupt, syscall.SIGPOOL, syscall.SIGCLD ...)

但这需要信号常数,我找不到与我想要捕获的信号相对应的常数。有任何想法吗?


守候你守候我
浏览 176回答 2
2回答

月关宝盒

简短的回答:您可以将新信号声明为 type 的类型化常量syscall.Signal:const (&nbsp; &nbsp; SIGRTMIN = syscall.Signal(0x22))长答案(它是如何工作的):signal.Notify函数签名是:Notify(c chan<- os.Signal, sig ...os.Signal)哪里os.Signal是这样定义的接口:// A Signal represents an operating system signal.// The usual underlying implementation is operating system-dependent:// on Unix it is syscall.Signal.type Signal interface {&nbsp; &nbsp; String() string&nbsp; &nbsp; Signal() // to distinguish from other Stringers}通常你会使用signal.Notify你的例子中的函数:signal.Notify(sigChan, os.Interrupt, syscall.SIGPOOL, syscall.SIGCLD ...)因此,如果我们检查包中这些常量的实现,syscall我们会看到:SIGKILL&nbsp; &nbsp;= Signal(0x9)包中的 thisSignal是syscall定义的类型:// A Signal is a number describing a process signal.// It implements the os.Signal interface.type Signal intfunc (s Signal) Signal() {}func (s Signal) String() string {&nbsp; &nbsp; // ... a few lines of code}它只是一个int带有无操作Signal()方法和 Stringer 实现的底层。int因此,您可以通过转换任意值来为要捕获的信号以相同的方式声明自己的常量:const (&nbsp; &nbsp; SIGRTMIN = syscall.Signal(0x22))signal.Notify(sigChan, SIGRTMIN, /* etc. */)

白猪掌柜的

- - - - - - - - - - - - - 回答 - - - - - - - - - - - - ---由于 [blackgreen][3],此问题已得到解决。我制作了一个小片段来轻松捕获所有 SIGRT 信号:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "syscall"&nbsp; &nbsp; "os/signal"&nbsp; &nbsp; "os")func getSIGRTchannel() chan os.Signal {&nbsp; &nbsp; sigChan := make(chan os.Signal, 1)&nbsp; &nbsp; sigArr := make([]os.Signal, 31)&nbsp; &nbsp; for i := range sigArr {&nbsp; &nbsp; &nbsp; &nbsp; sigArr[i] = syscall.Signal(i + 0x22)&nbsp; &nbsp; }&nbsp; &nbsp; signal.Notify(sigChan, sigArr...)&nbsp; &nbsp; return sigChan}func main() {&nbsp; &nbsp; c := getSIGRTchannel()&nbsp; &nbsp; // Block until a signal is received.&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; s := <-c&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Got signal:", s)&nbsp; &nbsp; }}要使用它,请在一个终端窗口中运行该程序并从另一个终端窗口向它发送一些信号。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go