1.基本概念
信号是发生事件时对进程的通知机制,也可以称为软件中断
信号的目的是用来通信的
1.硬件发生异常,将错误信息通知给内核,然后内核将相关的信号给相关的进程
2.在终端输入特殊字符产生特殊信号
3.进程调用kill()将任意信号发送给另一个进程或者进程组
4.发生了软件事件,借助软件触发条件,去进行通知
信号的分类:
1.忽略信号:进程直接不理会信号,除了SIGKILL 和 SIGSTOP
2.捕获信号:当信号达到进程后,执行预先绑定的信号处理函数【插一嘴,这不是就是pyqt5的信号与槽函数】,linux提供了signal()系统调用用于注册信号的处理函数
3. 执行系统的默认操作,进程不进行处理转而让系统进行处理
信号是异步的:
当产生了中断事件,然后告知程序,然后打断当前程序的正常执行流程,跳转去执行中断服务函数
信号的本质是int类型数字编号,从1开始
2.信号的分类
1.可靠信号和不可靠信号
不可靠信号(1-31) 可靠信号(32-64)
2.实时信号和非实时信号
非实时信号不支持排队,都是不可靠信号-----【标准信号】
实时信号支持排队,是可靠信号
3.进程对信号的处理
1.signal()函数
sig_t signal(int signum, sig_t handler);
signum:此参数指定需要进行设置的信号
handler:sig_t 类型的函数指针,指向信号对应的信号处理函数,当进程接收到信号后会自动执行该处
理函数
2.sigaction()函数
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
signum:需要设置的信号,除了 SIGKILL 信号和 SIGSTOP 信号之外的任何信号
act:描述了信号的处理方式,如果参数 act 为 NULL,则表示无需改变信号当前的处理方式
oldact:如果参数oldact 不为 NULL,则会将信号之前的处理方式等信息通过参数 oldact 返回出来
4.向进程发送信号
一个进程可通过kill()向另一个进程发送信号
int kill(pid_t pid, int sig);
pid:参数 pid 为正数的情况下,用于指定接收此信号的进程 pid
sig:参数 sig 指定需要发送的信号,也可设置为 0,如果参数 sig 设置为 0 则表示不发送信号,但任执
行错误检查,这通常可用于检查参数 pid 指定的进程是否存在。
kill()系统调用可将信号发送给指定的进程或者进程组中的每一个进程
发送进程的权限:
超级用户root: 进程可以将信号发送给任何进程
普通用户: 发送者进程的实际用户 ID 或有效用户 ID 必须等于接收者进程的实际用户 ID 或有效用户 ID
raise()
int raise(int sig);
sig : 需要发送的信号
alarm()和pause()函数
unsigned int alarm(unsigned int seconds);
设置定时器,当定时器时间到达的时候,内核会向进程发送SIGALR信号,只能触发一次
int pause(void);
pause()系统调用可以使得进程暂停运行、进入休眠状态,直到进程捕获到一个信号为止,只有执行了信
号处理函数并从其返回时,pause()才返回,在这种情况下,pause()返回-1,并且将 errno 设置为 EINTR
5.信号集
定义:一个可以表达多个信号(一组信号)的数据类型
初始化信号集:
int sigemptyset(sigset_t *set);
sigemptyset()初始化信号集,使其不包含任何信号
int sigfillset(sigset_t *set);
sigfillset()函数初始化信号集,使其包含所有信号(包括所有实时信号)
信号集添加/删除信号:
sigset_t *set: 信号集
signum:信号
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
测试信号是否在信号集
int sigismember(const sigset_t *set, int signum);
在:返回 1
不在:返回0
获取信号的描述信息
char *strsignal(int sig);
void psignal(int sig, const char *s);
信号掩码(阻塞信号传递)
处在信号掩码的信号会被阻塞,无法传递给进程进行处理,内核会将其阻塞,直到该信号从信号掩码中移除,内核才会把信号传递给进程从而进行处理
阻塞等待信号sigsuspend():
作用:将恢复信号掩码和pause()挂起进程两个动作封装成一个原子操作
int sigsuspend(const sigset_t *mask);
实时信号:
int sigpending(sigset_t *set);
set:处于等待状态的信号会存放在参数 set 所指向的信号集中
发送实时信号:
异常退出abort()函数
void abort(void);
正常终止进程:
1.main函数通过return 语句退出程序2.调用库函数exit()
3.系统调用终止进程,譬如exit(),_Exit()
异常终止进程:
1.被信号终止2.调用abort函数,SIGABRT