我目前使用的是 macOS Mojave 10.14.1。
如何获取 macOS 上发送信号的进程的 pid
10.14?我不记得在我之前使用的 10.12 上有过这个问题。
下面的代码简单地满足了您的愿望。如果您发送SIGTERM
,你可以看到发送进程的pid。
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
static void hdl (int sig, siginfo_t *siginfo, void *context)
{
printf ("Sending PID: %ld, UID: %ld\n",
(long)siginfo->si_pid, (long)siginfo->si_uid);
}
int main (int argc, char *argv[])
{
struct sigaction act;
fprintf(stderr, "%i pp %i\n",getpid(), getppid());
memset (&act, '\0', sizeof(act));
/* Use the sa_sigaction field because the handles has two additional parameters */
act.sa_sigaction = &hdl;
/* The SA_SIGINFO flag tells sigaction() to use the sa_sigaction field, not sa_handler. */
act.sa_flags = SA_SIGINFO;
if (sigaction(SIGTERM, &act, NULL) < 0) {
perror ("sigaction");
return 1;
}
while (1)
sleep (10);
return 0;
}
对于你的代码,
经验法则:即使您确定子进程结束了先前的父进程,也不要忘记执行埋葬程序。通过调用wait(...)
你告诉操作系统我已经为我的孩子完成了我的事情,所以现在你可以清理分配的字段等。
我更喜欢在分叉之前初始化信号实用程序,如果父进程没有机会注册信号操作怎么办?此外,我不明白你为什么要处理0
and 1
案件在switch
。本质上,这些案例不会被击中,因此总是被忽略。
另外,你没有使用break
在你的if
内的条件main()
。它进不去if
过了一段时间,以下情况是不可预见和不可取的,即该程序永远停留在while()
环形。我更愿意把signaled
进入状态while()
loop.
最后但并非最不重要的一点是,由于sleep()
调用子进程直到signaled
结果是0
, SIGTERM
多次被成功抓获。当发出信号时0
,循环停止。
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <memory.h>
#include <sys/wait.h>
volatile sig_atomic_t histogram[3] = {0,0,0};
volatile sig_atomic_t signaled = 0;
const int testsig = SIGTERM;
void sigaction_handler(int sig, siginfo_t* info, void* context)
{
switch (info->si_pid) {
case 0:
case 1:
histogram[info->si_pid]++;
break;
default:
fprintf(stderr, "sender pid -> %i\n", info->si_pid);
histogram[2]++;
break;
}
signaled = 1;
}
int main(int argc, const char * argv[]) {
struct sigaction sigAction;
memset( &sigAction, 0, sizeof( sigAction ) );
sigAction.sa_sigaction = sigaction_handler;
sigemptyset (&sigAction.sa_mask);
sigAction.sa_flags = SA_SIGINFO;
sigaction(testsig, &sigAction, NULL);
pid_t mainpid = getpid();
pid_t pid = fork();
if (pid == 0) {
fprintf(stderr, "my pid -> %i parent's pid-> %i\n", getpid(), getppid());
if (kill(mainpid, 0) == 0) { // signals are not queued not need loop
sleep(1);
kill(mainpid, testsig);
}
_exit(0);
} else {
wait(NULL); // play with this line to see what the difference is
while ( signaled ) {
printf("pid 0: %d, pid 1: %d, others: %d\n", histogram[0], histogram[1], histogram[2]);
signaled = 0;
sleep(1);
}
// wait(NULL); // play with this line to see what the difference is
}
}