如何在C语言中获取信号发送进程的PID?
获取信号发送进程PID的实现方法
要获取发送信号的进程PID,你不能依赖传统的signal()注册信号处理函数——它无法提供发送者的详细信息。正确的做法是使用sigaction()函数,它允许你指定带有siginfo_t参数的处理函数,这个结构体里就包含了发送信号的进程PID(si_pid字段)。
具体实现步骤:
定义带
siginfo_t参数的信号处理函数
函数签名需要符合void handler(int sig, siginfo_t *info, void *ucontext),通过info指针就能访问到发送者的PID信息。配置
sigaction结构体
设置sa_sigaction为你的处理函数,同时将sa_flags设为SA_SIGINFO,告诉系统要传递信号的详细元数据给处理函数。在main函数中注册信号规则
调用sigaction()将配置好的结构体与目标信号绑定,然后调用pause()等待信号触发。
完整代码示例
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> // 信号处理函数,获取并打印发送进程PID void signal_handler(int sig, siginfo_t *info, void *ucontext) { printf("收到信号%d,发送该信号的进程PID:%d\n", sig, info->si_pid); } int main() { printf("当前进程PID:%d\n", getpid()); printf("请用kill命令发送信号测试(例如:kill -SIGUSR1 %d)\n", getpid()); struct sigaction sa; // 初始化信号集,避免屏蔽额外信号 sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO; // 启用siginfo元数据传递 sa.sa_sigaction = signal_handler; // 指定自定义处理函数 // 注册SIGUSR1信号的处理规则 if (sigaction(SIGUSR1, &sa, NULL) == -1) { perror("sigaction 注册失败"); exit(EXIT_FAILURE); } // 暂停进程,等待信号触发 pause(); return 0; }
关键细节说明:
siginfo_t的si_pid字段就是发送信号的进程ID,若信号由内核触发(比如SIGSEGV),该值会是0。- 你可以将代码中的
SIGUSR1替换为其他需要处理的信号(如SIGINT、SIGTERM),只需同步修改sigaction的信号参数即可。 - 编译运行:用
gcc -o signal_pid signal_pid.c编译,运行后在另一个终端执行kill命令发送信号即可看到效果。
内容的提问来源于stack exchange,提问作者Ayfaise Ayfaise
相关产品推荐
相关产品推荐

