资讯动态

深入解析Linux信号处理机制

发布时间:2026/10/1 21:08:34 来源:尧图企业网站定制
一.信号信号是一种用户OS其他进程向目标进程发送异步事件的一种方式。在详细的学习信号时我们先提出几个问题带着问题去学习1.你怎么能识别信号呢识别信号是内置的。进程认识信号是程序员内置的特性。2.信号产生之后怎么处理的如果没有产生信号怎么处理信号的处理方法在信号产生之前就已经准备好了。3.处理信号是立即处理吗如果我在做优先级很高的事情可能并不是优先处理的。4.怎么处理信号a.默认行为b.忽略信号c.自定义- 实际执行信号的处理动作称为信号递达(Delivery)- 信号从产生到递达之间的状态称为信号未决(Pending)- 进程可以选择阻塞(Block)某个信号阻塞特定信号信号产生了一定把信号要进行pending永远不递达除非我们解除阻塞- 被阻塞的信号产生时将保持在未决状态直到进程解除对此信号的阻塞才执行递达的动作- 注意阻塞和忽略是不同的只要信号被阻塞就不会递达而忽略是在递达之后可选的一种处理动作二.所需要学习的函数1.sgnalsignal是一个用于信号处理的库函数主要作用是为特定的信号如中断、终止、非法操作等设置一个自定义的处理函数从而改变程序收到该信号时的默认行为。捕获信号让程序在收到某个信号时执行你写的代码例如清理资源、记录日志、忽略信号。恢复默认把某个信号的处理方式恢复为系统默认动作。忽略信号让程序忽略某些信号例如SIGINT按 CtrlC 时不中断。#include signal.hvoid (*signal(int sig, void (*handler)(int)))(int);// 更易理解的版本typedef void (*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);sig要处理的信号编号例如SIGINTCtrlC 中断信号SIGTERM终止信号SIGSEGV段错误非法内存访问handler三种取值之一SIG_IGN→ 忽略该信号SIG_DFL→ 恢复默认处理通常是终止程序自定义函数指针 → 执行你写的处理逻辑2.killkill的作用是向一个进程发送信号。它不一定是杀死进程而是告诉进程你该做什么。#include sys/types.h#include signal.hint kill(pid_t pid, int sig);参数详解第一个参数pid_t pid目标进程pid 值含义 0发送给指定 PID 的单个进程 0发送给当前进程所在进程组的所有进程 -1发送给调用进程有权发送信号的所有进程不包括 init/systemd 进程 -1发送给进程组 ID |pid|的所有进程如 pid-1234发给进程组1234第二个参数int sig信号编号值含义0空信号不真正发送仅用于检查进程是否存在1~31标准 Unix 信号如 9SIGKILL, 15SIGTERM34~64实时信号Linux 扩展返回值含义0成功。至少有一个信号被成功发送-1失败。此时需要查看errno获取具体错误原因3.raiseraise()是一个库函数用于进程向自己发送信号。与 kill() 的区别函数发送方向kill()向其他进程或自己发送信号raise()只能向自己发送信号#include signal.hint raise(int sig);参数含义sig要发送的信号编号如SIGTERM、SIGKILL、SIGINT返回值含义0成功非0失败4.abordabort()是一个库函数用于异常终止当前进程并生成 core dump核心转储文件用于调试。abort()让程序非正常崩溃而不是正常退出。#include stdlib.hvoid abort(void);注意abort()没有返回值因为它永远不会正常返回。他对应的是6号。5.alarmalarm()是一个系统调用用于设置一个定时器在指定秒数后向自己发送SIGALRM信号。设置一个闹钟N 秒后给自己发一个SIGALRM信号。#include unistd.hunsigned int alarm(unsigned int seconds);参数含义seconds定时秒数0 表示取消之前的闹钟返回值含义0之前没有设置过闹钟0之前闹钟剩余的秒数如果之前有未触发的闹钟每个进程只有一个闹钟再次调用alarm()会重置之前的闹钟到达指定时间后进程收到SIGALRM信号默认行为是终止进程如果seconds 0取消当前闹钟不设置新闹钟6.pausepause()是一个系统调用用于让进程挂起睡眠直到收到一个信号。让进程停下来睡觉直到被信号唤醒。#include unistd.hint pause(void);返回值含义-1总是返回 -1因为被信号中断注意pause()永远不返回 0它只会在收到信号后返回 -1并设置errno为EINTR。errno含义EINTR被信号中断正常情况调用pause()的进程会一直挂起进入睡眠状态进程不占用 CPU 时间直到收到一个信号并且该信号的处理函数执行完毕后pause()才返回如果信号默认行为是终止进程则pause()永远不会返回7.sigactionsigaction是一个功能强大且灵活的 POSIX 系统调用用于检查和更改进程接收到特定信号时的行为。与signal函数相比它提供了更精细的控制、更好的跨平台移植性是编写健壮信号处理程序的推荐方法#include signal.h int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);signum指定要操作的信号可以是除SIGKILL和SIGSTOP之外的任何信号。act如果非空则指向一个struct sigaction结构体用于设置新的信号处理行为。oldact如果非空则用于保存之前的信号处理行为方便之后恢复。返回值成功时返回0失败时返回-1并设置errno以指示错误️ 核心数据结构struct sigaction这是sigaction的核心其定义大致如下struct sigaction { void (*sa_handler)(int); // 简单的信号处理函数指针 void (*sa_sigaction)(int, siginfo_t *, void *); // 可接收额外信息的处理函数 sigset_t sa_mask; // 处理函数执行时要额外阻塞的信号集 int sa_flags; // 用于修改信号行为的标志位 void (*sa_restorer)(void); // 已废弃仅供内部使用无需关注 };void (*sa_handler)(int);这个就是我们在signal中的hander函数。三.sigset_tsigset_t是一个信号集类型用于表示多个信号的集合。头文件#include signal.h五个核心函数函数功能相当于位操作sigemptyset()清空信号集全部置0set 0sigfillset()填满信号集全部置1set ~0sigaddset()添加一个信号置1set | (1 sig)sigdelset()删除一个信号置0set ~(1 sig)sigismember()测试信号是否存在读位(set sig) 11.sigprocmask():修改block表sigprocmask()是一个系统调用用于读取或修改进程的信号屏蔽字决定哪些信号被阻塞暂时不递送。设置或获取进程的信号黑名单被屏蔽的信号暂时不会被进程处理。#include signal.hint sigprocmask(int how, const sigset_t *set, sigset_t *oldset);第一个参数how操作方式how 值含义公式SIG_BLOCK将set中的信号添加到当前屏蔽字mask mask | setSIG_UNBLOCK将set中的信号从当前屏蔽字移除mask mask ~setSIG_SETMASK将当前屏蔽字设置为setmask set第二个参数set新屏蔽集指向要设置的信号集可以为NULL此时how被忽略用于仅查询第三个参数oldset旧屏蔽集用于保存修改前的信号屏蔽字可以为NULL不保存旧值返回值返回值含义0成功-1失败并设置errno错误码errno含义EINVALhow参数无效EFAULTset或oldset指针无效每个进程都有一个信号屏蔽字是一个信号集表示当前被阻塞的信号sigset_t pending; // 被阻塞的信号会进入待处理状态重要规则被屏蔽的信号不会丢失只是暂时不递送当解除屏蔽后信号会被递送SIGKILL和SIGSTOP不能被屏蔽2.sigpending():pending表sigpending()是一个系统调用用于获取进程当前被阻塞挂起的待处理信号。查看哪些信号被阻塞了但还没有被处理即已经到达但因为被屏蔽而排队等待的信号。#include signal.hint sigpending(sigset_t *set);参数含义set指向sigset_t的指针用于返回当前待处理的信号集返回值含义0成功-1失败并设置errno注意在 Linux 中sigpending()总是成功返回 0但为了可移植性仍应检查返回值。信号生命周期 发送信号 → 是否被屏蔽 ↓ ↓ 否 是 ↓ ↓ 立即递送 进入待处理队列 给进程处理 (pending状态) ↓ 解除屏蔽后 ↓ 立即递送关键点待处理信号已经发送给进程但因为被屏蔽暂时无法递送每个信号在待处理队列中只有一个重复发送不会排队多次解除屏蔽后待处理信号会立即被递送

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑