我有一个获得SIG TERM
的java应用程序。我想知道发送此信号的过程的pid
这可能吗?
答案 0 :(得分:30)
两种特定于Linux的方法是SA_SIGINFO
和signalfd()
,它们允许程序接收有关发送信号的非常详细信息,包括发送方的PID。
致电sigaction()
并传递struct sigaction
sa_sigaction
,SA_SIGINFO
中包含所需的信号处理程序,sa_flags
中的siginfo_t
标记设置为signalfd_siginfo
。使用此标志,您的信号处理程序将接收三个参数,其中一个是包含发送方PID和UID的siginfo_t
结构。
调用signalfd()
并从中读取{{1}}结构(通常在某种select / poll循环中)。内容类似于{{1}}。
使用哪一个取决于您的应用程序的编写方式;它们可能在普通C之外不能正常工作,我也没有希望让它们在Java中工作。它们在Linux之外也是不可移植的。他们也可能是你正在努力实现目标的非常错误的方式。
答案 1 :(得分:9)
我还需要在程序中识别信号发送者,所以我使用了grawity' answer,并在我的程序中使用它,它运行良好。
以下是示例代码:
<强> 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
以终止自身之前,程序会将SIGQUIT
发送给自己10次。
此外,在执行期间,按 CTRL + C 发送SIGINT
,或 CTRL + \ < / kbd>发送SIGQUIT
手动终止程序。
该程序可以成功识别发送信号的人。
答案 2 :(得分:1)
不,信号不是作为进程间通信通道。据我所知,没有PID通过。发送PID与我在信号中看到的所有用途无关。您可以相对确定发送信号的进程具有root权限,或者属于与进程相同的UID。
发送信号的过程可能不再存在。如果使用kill命令而不是内置shell,则几乎可以肯定该进程不再存在。
从Java方面来看,这更加困难。该过程在Java虚拟机中运行,该虚拟机从操作系统中抽象出来。并非此计算机存在所有操作系统概念。
答案 3 :(得分:1)