在Linux系统中,信号是一种用于进程间通信或控制的异步事件机制。无论是初学者还是资深开发者,理解Linux信号的发送、保存与处理都是掌握系统编程的关键。本文将用最通俗的语言,带你彻底搞懂这一主题。
信号可以看作是一种“软件中断”,它通知进程某个事件发生了。例如,按下 Ctrl+C 会向前台进程发送 SIGINT 信号,默认终止进程。信号贯穿了整个进程通信的方方面面,是系统编程的基石。
信号的发送者可以是内核、其他进程或自身。常见发送方式包括:
SIGFPE。Ctrl+Z 发送 SIGTSTP。kill()、raise()、alarm() 等函数。其中 kill(pid, sig) 可以向指定进程发送信号,而 raise(sig) 则是向自己发送信号。
当信号发出后,并不会立即被处理,而是先保存在进程的PCB(进程控制块)中。每个进程维护两个关键的信号集:
通过系统调用 sigprocmask() 可以修改阻塞信号集,而 sigpending() 则可以获取当前未决信号集。这两个函数是信号集操作的核心工具。
信号的完整生命周期包括:产生(发送)→ 未决(pending)→ 递达(delivery)。当信号被递达时,进程会执行默认操作、忽略或调用自定义的信号处理函数。但如果信号在阻塞集中被屏蔽,它将一直停留在未决状态,直到解除阻塞才会递达。
例如:一个进程通过 sigprocmask() 阻塞了 SIGINT,那么即使你狂按 Ctrl+C,该信号也只会停留在未决队列中,直到进程解除对 SIGINT 的阻塞,才会真正处理。
#include #include int main() {sigset_t newmask, oldmask;sigemptyset(&newmask);sigaddset(&newmask, SIGINT); // 阻塞SIGINT// 设置阻塞集sigprocmask(SIG_BLOCK, &newmask, &oldmask);printf("SIGINT 已被阻塞,按 Ctrl+C 试试?");sleep(5);// 检查未决信号sigset_t pend;sigpending(&pend);if (sigismember(&pend, SIGINT))printf("SIGINT 处于未决状态");// 恢复原阻塞集(即解除阻塞)sigprocmask(SIG_SETMASK, &oldmask, NULL);printf("SIGINT 已解除阻塞,将立即处理");sleep(3); // 此时若之前有SIGINT未决,会递达return 0;} 这个例子展示了如何利用信号集操作控制信号的阻塞与未决,是理解保存机制的最佳实践。
信号的发送和保存是Linux系统中进程通信的重要组成部分。通过掌握信号的内核数据结构(pending和block集)以及相关系统调用,你可以更灵活地控制进程的行为,避免竞态条件,编写出更健壮的程序。希望本文能帮你理清这一脉络,在实际开发中游刃有余。
—— 本文围绕Linux信号、进程通信、信号处理、信号集操作四个核心关键词展开,助你构建完整知识体系。
本文由主机测评网于2026-03-08发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:http://www.vpshk.cn/20260329552.html