我正在使用Go启动一些脚本,当它们遇到问题时,它们会使用“警报”信号,我知道Go可以捕获这些信号,但我需要知道产生该信号的PID。在C中向信号处理程序传递一个结构以了解发出信号的pid,但在Go中看起来并非如此
package main import ( "fmt" "os" "os/signal" ) func main() { c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, os.Kill) s := <-c fmt.Println("Got signal:", s) fmt.Printf("%+v\n",s) }
下面的示例(从信号文档中提取)向我发送了发起呼叫的信号,但没有任何有用的信息(例如pid)
不,您不能以官方支持的方式执行此操作。Go运行时需要拥有信号处理程序,并且不会以任何方式公开额外的信息。
通过设置新的信号处理程序,您仍然可以从C中做到这一点,但是我对此会非常谨慎(请参阅诸如issue / 7227之类的问题)。您最好使用信号以外的其他通信方法。
这是一个基于Ian从问题7227开始的代码的部分示例:
package main /* #include <stdio.h> #include <signal.h> #include <string.h> struct sigaction old_action; void handler(int signum, siginfo_t *info, void *context) { printf("Sent by %d\n", info->si_pid); } void test() { struct sigaction action; sigaction(SIGUSR1, NULL, &action); memset(&action, 0, sizeof action); sigfillset(&action.sa_mask); action.sa_sigaction = handler; action.sa_flags = SA_NOCLDSTOP | SA_SIGINFO | SA_ONSTACK; sigaction(SIGUSR1, &action, &old_action); } */ import "C" import ( "os" "syscall" "time" ) func main() { C.test() pid := os.Getpid() for { syscall.Kill(pid, syscall.SIGUSR1) time.Sleep(time.Second) } }