如何用struct sigaction和struct itimerval处理双信号?代码单信号触发问题排查
问题分析与修复方案
兄弟,我瞅了你的代码,核心问题是你只用到了一个struct sigaction结构体,而且大概率没给两个信号分别做正确的注册配置——要么是用同一个结构体覆盖了之前的设置,要么干脆没给第二个信号单独调用sigaction(),结果就只有一个信号的处理函数能触发。
具体哪儿错了?
- 你只声明了一个
struct sigaction sig变量,但每个信号的处理配置(比如回调函数、信号掩码、标志位)都需要单独设置,用同一个结构体去搞两个信号,后面的配置会把前面的冲掉。 - 另外,你大概率没设置
SA_SIGINFO这个关键标志——如果要用带siginfo_t参数的回调函数(就是你写的fun和fun2这种),必须在sa_flags里加上这个标志,不然系统不会调用你写的这些回调,甚至可能直接用默认的信号处理逻辑。 - 还有,
sa_mask也没初始化,这可能导致处理信号时被其他信号干扰,或者出现意外的阻塞情况。
改好的代码示例
#include <stdio.h> #include <signal.h> #include <unistd.h> #include <errno.h> //信号处理函数 void fun(int sig, siginfo_t *siginfo,void *ptr) { printf("si_code=%d\n",siginfo->si_code); printf("siGNO1=%d\n",siginfo->si_signo); printf("incoming\n"); } void fun2(int sig,siginfo_t *siginfo,void *ptr) { printf("si_fd=%d\n",siginfo->si_fd); printf("signal2\n"); } int main() { struct sigaction sig_config1, sig_config2; // 给第一个信号(比如SIGUSR1)做配置 sig_config1.sa_sigaction = fun; sigemptyset(&sig_config1.sa_mask); // 清空掩码,处理时不阻塞其他信号(按需调整) sig_config1.sa_flags = SA_SIGINFO; // 必须加这个,才能用带siginfo的回调 if (sigaction(SIGUSR1, &sig_config1, NULL) == -1) { perror("注册SIGUSR1失败"); return errno; } // 给第二个信号(比如SIGIO)做配置 sig_config2.sa_sigaction = fun2; sigemptyset(&sig_config2.sa_mask); sig_config2.sa_flags = SA_SIGINFO; if (sigaction(SIGIO, &sig_config2, NULL) == -1) { perror("注册SIGIO失败"); return errno; } // 挂起进程等待信号 while(1) { pause(); } return 0; }
几个必须注意的点
- 每个信号单独用一个
struct sigaction结构体,别偷懒共用一个,不然配置会被覆盖。 - 一定要加
SA_SIGINFO标志,这是使用带siginfo_t参数回调的前提,没加的话你的fun和fun2根本不会被正确调用。 - 初始化
sa_mask:用sigemptyset清空是最稳妥的基础操作,要是有需要,也可以用sigaddset添加要阻塞的信号,防止处理当前信号时被其他信号打断。 - 调用
sigaction()后记得检查返回值,出问题了能快速定位是哪个信号注册失败。
内容的提问来源于stack exchange,提问作者user9478215
相关产品推荐
相关产品推荐

