信号是Linux系统中进程间通信和控制的一种重要机制,它类似于日常生活中的“暗号”——当某个事件发生时,内核向进程发送一个信号,进程收到后立即采取预设的动作。本文将从零开始,带你深入探索Linux信号的方方面面,让你轻松掌握这一艺术。
信号本质上是一种软件中断,它通知进程某个事件已经发生。例如,当你在终端按下Ctrl+C,内核会向前台进程发送SIGINT信号,默认终止该进程。这种机制让进程能够对异步事件做出反应,而不需要持续轮询检查。
信号可以由多种方式产生:
SIGFPE(浮点异常),非法内存访问产生SIGSEGV(段错误)。Ctrl+C产生SIGINT,Ctrl+\产生SIGQUIT。alarm()定时器到期产生SIGALRM,kill()函数向指定进程发送任意信号。raise()给自己发信号,abort()产生SIGABRT。| 信号编号 | 信号名称 | 默认动作 | 说明 |
|---|---|---|---|
| 1 | SIGHUP | 终止 | 终端挂断或控制进程终止 |
| 2 | SIGINT | 终止 | 键盘中断(Ctrl+C) |
| 9 | SIGKILL | 终止 | 强制杀死进程(不可捕获/忽略) |
| 11 | SIGSEGV | 终止 (core) | 段错误(无效内存引用) |
进程收到信号后,可以采取三种处理方式:
SIGKILL和SIGSTOP不能被忽略。signal()或sigaction()注册一个函数,当信号到达时调用该函数执行特定操作。为了防止信号在关键时刻打断进程,Linux提供了信号阻塞机制。每个进程都有一个信号掩码(阻塞集),用于指定当前要阻塞哪些信号。当信号被阻塞时,它不会立即递达,而是保持在“未决”状态(pending)。一旦解除阻塞,信号就会被递达。
上图展示了信号从产生、阻塞、未决到最终递达的完整过程。通过sigprocmask()可以修改阻塞集,sigpending()可以查看未决信号。
下面是一个简单的C程序,演示如何捕获SIGINT并自定义处理:
#include #include #include void handler(int sig) { printf("捕获到信号 %d,按Ctrl+C试试?", sig);}int main() { signal(SIGINT, handler); // 注册自定义处理函数 while(1) { printf("运行中..."); sleep(1); } return 0;} 编译运行后,每次按下Ctrl+C,程序不会终止,而是打印消息并继续运行。注意,SIGKILL和SIGSTOP不能自定义处理,因此你可以用kill -9强制结束程序。
信号是Linux系统编程中不可或缺的工具,理解进程信号的产生、传递和处理,对于编写健壮的程序至关重要。通过本文,你应该对信号处理和信号阻塞有了清晰的认识。实际应用中,还需注意信号的可重入性、异步安全函数等高级话题,但基础已足够让你迈出第一步。
希望这篇文章能帮助你领略到Linux信号的艺术之美,在未来的编程中灵活运用!
本文由主机测评网于2026-03-11发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://vpshk.cn/20260330534.html