You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何进程处理已阻塞信号?SIGINT阻塞代码的技术疑问

问题分析与解决

嘿,你对信号阻塞的理解其实是对的——阻塞的信号会被内核挂起,不会递送到进程处理,直到你解除阻塞。但你的代码里有个致命的野指针错误,导致你根本没成功阻塞SIGINT,这才是按下Ctrl+C后依然触发handler的原因。

代码里的核心问题

看这段代码:

sigset_t *ss;
sigemptyset(ss);
sigaddset(ss, SIGINT);

这里你只声明了一个sigset_t类型的指针ss,但没有给它分配任何有效的内存空间,也没有让它指向一个实际存在的sigset_t变量。sigemptyset和sigaddset函数需要的是一个合法的sigset_t对象的地址,操作野指针会触发未定义行为——可能会破坏进程的内存,也可能完全没修改到预期的信号集,导致后续的sigprocmask调用根本没起到阻塞SIGINT的作用。

修正后的代码

把指针改成栈上的sigset_t变量,再传递它的地址给相关函数:

void handler(int signum){ printf("handling %d\n", signum); }
int main() {
    signal(SIGINT, handler);
    sigset_t ss; // 声明一个实际的sigset_t变量
    sigemptyset(&ss); // 传递变量的地址
    sigaddset(&ss, SIGINT);
    sigprocmask(SIG_BLOCK, &ss, NULL);
    for(;;);
    return 0;
}

验证效果

运行修正后的程序,按下Ctrl+C,你会发现终端没有输出任何内容——这符合你的预期,因为SIGINT已经被成功阻塞,信号处于pending状态,不会被递送到进程处理。如果之后你调用sigprocmask(SIG_UNBLOCK, &ss, NULL)解除阻塞,内核就会立刻递送这个pending的SIGINT,触发handler输出内容。

内容的提问来源于stack exchange,提问作者user4180854

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:34:16