我怎么能在Linux中告诉哪个进程发送了我的进程信号

我有一个获得SIG TERM的Java应用程序。 我想知道发送这个信号的过程的PID。
那可能吗?

Solutions Collecting From Web of "我怎么能在Linux中告诉哪个进程发送了我的进程信号"

两个特定于Linux的方法是SA_SIGINFOsignalfd() ,它允许程序接收关于发送的信号的非常详细的信息,包括发送者的PID。

  • 调用sigaction()并传递一个struct sigaction ,它在sa_sigaction具有所需的信号处理程序,在sa_flags设置SA_SIGINFO标志。 有了这个标志,你的信号处理程序将接收三个参数,其中一个是包含发送者的PID和UID的siginfo_t结构。

  • 调用signalfd()signalfd_siginfo读取signalfd_siginfo结构(通常在某种选择/轮询循环中)。 内容将类似于siginfo_t

使用哪一个取决于你的应用程序的写法; 他们可能不会在C语言以外工作,我也不希望让他们在Java中工作。 它们在Linux之外也是不可移植的。 他们也可能是做你正在努力实现的非常错误的方式。

我还需要在一个程序中识别信号发送者,所以我拿出grawity的答案 ,并在我的程序中使用它,它运作良好。

以下是示例代码:

send_signal_raise.c

 // send signal to self test - raise() #include <stdio.h> #include <signal.h> #include <pthread.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <string.h> static int int_count = 0, max_int = 5; static struct sigaction siga; static void multi_handler(int sig, siginfo_t *siginfo, void *context) { // get pid of sender, pid_t sender_pid = siginfo->si_pid; if(sig == SIGINT) { int_count++; printf("INT(%d), from [%d]\n", int_count, (int)sender_pid); return; } else if(sig == SIGQUIT) { printf("Quit, bye, from [%d]\n", (int)sender_pid); exit(0); } return; } int raise_test() { // print pid printf("process [%d] started.\n", (int)getpid()); // prepare sigaction siga.sa_sigaction = *multi_handler; siga.sa_flags |= SA_SIGINFO; // get detail info // change signal action, if(sigaction(SIGINT, &siga, NULL) != 0) { printf("error sigaction()"); return errno; } if(sigaction(SIGQUIT, &siga, NULL) != 0) { printf("error sigaction()"); return errno; } // use "ctrl + c" to send SIGINT, and "ctrl + \" to send SIGQUIT, int sig; while(1) { if(int_count < max_int) { sig = SIGINT; } else { sig = SIGQUIT; } raise(sig); // send signal to itself, sleep(1); // sleep a while, note that: SIGINT will interrupt this, and make program wake up, } return 0; } int main(int argc, char *argv[]) { raise_test(); return 0; } 

编译:

gcc -pthread -Wall send_signal_raise.c

执行:

./a.out

它能做什么:

程序发送SIGINT到自己10次,然后发送SIGQUIT自行终止。

另外,在执行过程中,按CTRL + C发送SIGINT ,或按CTRL + \发送SIGQUIT ,手动终止程序。

该程序可以成功识别谁发送信号。

不,信号不是作为进程间通信信道。 据我所知,没有PID通过。 发送PID与我所见过的所有信号无关。 您可以相对确定发送信号的进程是否具有root权限,或者属于与您的进程相同的UID。

发送信号的过程可能不再存在。 如果使用kill命令而不是内置的shell,那么几乎可以确定该进程不再存在。

从Java方面来说,这更加困难。 该进程运行在Java虚拟机中,该虚拟机是从操作系统中抽象出来的。 并非所有的操作系​​统概念都存在于这台机器上