UNIX,Linux,信号详解

本文深入讲解了信号的概念,包括信号的类型、处理方式以及常见信号的介绍。详细阐述了信号的捕获、发送和休眠功能,同时探讨了信号集与信号屏蔽的机制,为读者提供了全面的信号处理知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、什么是信号
信号是一种中断,即中止(注意不是终止)当前正在执行的任务,转而执行其它任务(可能返回也可能不返回),中断分为硬件中断(硬件设备产生的中断)和软件中断(其它程序产生的中断)。
软中断信号(signal,又简称为信号)用来通知进程发生了异步事件。进程之间可以互相通过系统调用kill发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。注
意,信号只是用来通知某进程发生了什么事件,并不给该进程传递任何数据。

二、信号的处理
1、忽略。
2、终止进程。
3、终止进程并产生core文件。
4、捕获信号并处理。

三、常见的信号
SIGINT(2) Ctrl+c 产生的信号
SIGQUIT(3) Ctrl+* 产生的信号
SIGABRT(6) 调用
abort*函数,产生此信号
SIGFPE(8) 浮点数例外,除以0、浮点溢出等
SIGKILL(9) 不能被捕获或忽略,常用于杀死进程
SIGSEGV(11) 段错误信号,非法访问内存产生的信号
SIGTSTP(20) Ctrl+z 生产的信号
SIGCHLD(17) 子进程状态改变信号
注意:在终端中执行 kill -l 可以显示出所有信号
以下是比较常见的全部信号
在这里插入图片描述在这里插入图片描述四、信号的捕获

sighandler_t signal(int signum, sighandler_t handler);

功能:信号处理注册函数。
signum:信号的编号(1~31),也可以是宏。
sighandler_t handler:是函数指针,模型:typedef void (*sighandler_t)(int);
注意:在某些UNIX系统上,signal注册的函数只执行一次,执行完后就恢复成默认处理方式,如果长期使用该函数处理信号,可以在函数结束前再注册一次。

五、发送信号

int kill(pid_t pid, int sig);

功能:向指定的进程发送信号。
pid > 0 :向进程号为pid的进程发送信号。
pid = 0 : 向进程组发送信号。
pid = -1 :向所有(有权利发送信号的)进程发送信号。
pid < -1 : 向进程号为绝对值pid的进程号发送信号。
sig:信号的编号。sig为0时,kill不会发送信号,但是会进行错误检查(检查进程号或者进程组id是否存在)。

int raise(int sig);

功能:向当前进程发送信号。
**sig:**信号的编号。

六、休眠

int pause(void);

功能:一旦执行,进程就会进行无尽的休眠(暂停),知道遇到信号。先执行信号处理函数才会从休眠中醒来。

unsigned int sleep(unsigned int seconds);

功能:休眠指定秒数,当有信号来临时会提前醒来,提前醒来会返回剩余的秒数。
**seconds:**休眠的秒数。

七、闹钟

unsigned int alarm(unsigned int seconds);

功能:告诉内核seconds秒后发送SIGALRM信号
seconds:秒数。
返回值:如果之前设定的时间还没有到,则会重新设置(覆盖),并返回之前设置的剩余秒数。

八、信号集与信号屏蔽

信号集:信号的集合,由128位二进制组成,每一位代表一个信号。
注意:当信号集里面的位数为1时表示的是要屏蔽这个信号。

信号屏蔽:当做一些特殊操作时,我们会希望有些信号来而有些信号不要来,而与设置信号忽略不同的,信号屏蔽只是暂时不来,并且可以获取这段时间发生哪些信号。
注意:每个进程都有一个信号掩码(信号集)。

int sigemptyset(sigset_t* set);

功能:清空信号集,把所有位设置为0。
*sigset_t set:**定义的信号集

int sigfillset(sigset_t* set);

功能:把信号集所有的位置为1。

int sigaddset(sigset_t* set,int signum);

功能:往信号集里面添加一个信号。
int signum:信号。

int sigdelset(sigset_t* set,int signum);

功能:删除信号集里面的一个信号。

int sigismember(const sigset_t *set, int signum);

功能:判断信号里面有没有signum信号。

int sigprocmask(int  how,  const  sigset_t  *set,sigset_t *oldset);

功能:检查,修改进程的信号掩码
how:
SIG_BLOCK 设置当前信号掩码与set的并集为新的信号掩码,添加。
SIG_UNBLOCK 新的信号掩码是当前掩码与set补集的交集,删除。
SIG_SETMASKset当作新的信号掩码,重新设置。

set:可以为空,则获取信号掩码。
oldset:旧的信号屏幕掩码。

int sigpending(sigset_t *set);

功能:获取信号屏蔽期间发生的信号,当信号屏蔽解除后就没了。

注意:在信号屏蔽期间发生的信号,无论多少次(不可靠信号),只能捕获一次。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值