Linux信号

简介: Linux信号

一、信号不是信号量


1.信号与信号量的区别


信号量是实现进程间同步与互斥的一种技术!


信号是一种软件中断,是一种事件通知机制!


       信号通知进程发生了某个事件,打断进程当前的操作,去处理这个事件;


       一个信号代表一个事件,且信号一定是可识别的。


2.信号分类


信号查看: kill -l


共有62种信号:


       1-31号:继承之unix,是不可靠信号,非实时信号;


       34-64号:后期扩展而来,是可靠信号,是实时信号。


1.png


二、信号生命周期


产生->注册->注销->处理,(阻塞)


1.信号产生


1.1 硬件产生


通过中断按键操作产生,


例如:ctrl+c / ctrl+z / ctrl+\


1.2 软件产生


通过调用系统函数产生,例如:


int kill(pid_t pid, int signum);


       kill命令就是通过调用kill函数实现,kill函数可以给一个指定的进程发送指定的信号。


       kill命令杀死进程的原理:给进程发送一个终止信号


int rease(int signum);


       rease函数可以给当前进程发送指定的信号(自己给自己发送信号)。


void abort();


       abort函数使当前进程接收到信号而异常终止。


unsigned int alarm(unsigned int seconds);


       alarm函数可以设定一个时钟,相当于告诉内核在seconds秒后给当前进程发送SIGALRM信号,该信号的默认处理方式是终止当前进程。


2.信号注册

2.1 作用


       让进程知道自己收到了某个信号


2.2 原理


       在进程pcb中有一个pending位图(未决信号集合),也就是当前进程收到了,但是暂时还未被处理的信号集合。


       信号的注册:就是在这个位图中标记信号值对应位置为1,并且在pcb中存在一个sigqueue链表,在这个链表中添加对应的信号节点。


2.3 可靠信号与非可靠信号的注册


1)可靠信号的注册:


       无论当前是否有相同信号已经注册,都对位图置1,并在sigqueue链表添加一个节点。


2)非可靠信号的注册:


       如果没有相同信号已经被注册,则注册;否则,直接返回。


非可靠信号注册存在的问题:可能存在事件丢失的情况。


3.信号注销


3.1 作用


       在处理信号前,将信号存在的痕迹抹除。


3.2 原理


       将sigqueue链表中对应信号的节点删除掉,并修改位图。


           可靠信号:删除一个节点,当没有相同信号节点时,再去修改位图。


           非可靠信号:删除信号的节点,直接修改位图置0。


4.信号处理


4.1 原理


       处理一个信号,实际上就是调用这个信号的处理函数。


4.2 处理方式


       默认处理方式:系统中已经定义好的处理方式。


       忽略处理方式:对信号的处理就是忽略,什么都不做。


       自定义处理方式:用户自己定义处理函数,然后替换掉内核中的默认处理方式。


系统接口:


typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
        signum:指定的信号值
        handler:处理方式
                SIG_DFL:默认处理方式
                SIG_IGN:忽略处理方式


返回值:


       该信号原来的处理方式。


用户自定义:


void sigcb(int signum){……}
利用函数回调,处理对应信号:
        signal(1, sigcb);
        signal(2, sigcb);
        ……;


自定义处理方式的信号捕捉流程:


       1.信号处理的时机:


           程序从内核态切换回用户态之前,会先进行信号处理


       2.信号的处理


           信号的处理是一次性将所有的信号处理完毕之后,才会返回到用户态主控流程。


5.信号阻塞


5.1 功能


       阻塞一个信号,指的就是暂时不去处理这个信号。


       在pcb中,存在一个block信号阻塞集合,在这个集合中,标记哪个信号,就代表着要阻塞哪个信号,意味着当收到这个信号时,不去处理。


5.2操作接口


int sigprocmask(int how, sigset_t *set, sigset_t *old);
        how:要对阻塞集合进行的操作;
                SIG_BLOCK:相当于 block |= set
                    将set集合中的信号添加到block集合中。
                SIG_UNBLOCK:相当于 block &= ~set
                    将set集合中的信号从block集合中移除。
                SIG_SETMASK:相当于 block = set
                    将set集合中的信号设置为block集合信号
        set:要操作的信号集合;
        old:用于保存修改前block集合中的数据。


辅助操作接口:


int sigemptyset(sigset_t *set);清空set集合
int sigfillset(sigset_t *set);填充所有信号到集合中
int sigaddset(sigset_t *set, int signum);添加指定信号到集合中
int sigdelset(sigset_t *set, int signum);从指定集合中移除指定信号
int sigismember(const sigset_t *set, int signum);判断指定信号是否在集合中


5.3 两个特殊的信号


SIGKILL -9 & SIGSTOP -19;


       这两个信号不会被阻塞、不会被忽略、不会被自定义。也就是说,这两个信号的处理方式无法被修改。


三、信号的应用


1. SIGCHLD信号


SIGCHLD:子进程退出后,通知父进程的信号。


常见应用:


signal(SIGCHLD, SIG_IGN);


       手动设置处理方式为忽略处理方式。


此时手动设置为忽略处理方式:


       意味着用户对此信号不关心,系统会自动处理,释放相关资源。


2. SIGPIPE信号


SIGPIPE:所有管道读端关闭后,继续write所触发的异常信号。


常见应用:


 

signal(SIGPIPE, SIG_IGN);


       手动设置处理方式为忽略处理方式。


此时手动设置为忽略处理方式:


       意味着用户对此信号不关心,系统会自动处理,释放相关资源。


相关文章
|
6月前
|
Ubuntu Linux
【Linux】详解信号产生的方式
【Linux】详解信号产生的方式
|
6月前
|
Unix Linux
【Linux】详解信号的分类&&如何自定义信号的作用
【Linux】详解信号的分类&&如何自定义信号的作用
|
3月前
|
Linux 调度
Linux0.11 信号(十二)(下)
Linux0.11 信号(十二)
25 1
|
3月前
|
存储 Linux 调度
|
3月前
|
存储 Unix Linux
Linux0.11 信号(十二)(上)
Linux0.11 信号(十二)
31 0
|
3月前
|
Linux
|
4月前
|
安全 小程序 Linux
Linux中信号是什么?Ctrl + c后到底为什么会中断程序?
信号在进程的学习中是一个非常好用的存在,它是软件层次上对中断机制的一种模拟,是异步通信方式,同时也可以用来检测用户空间到底发生了什么情况,然后系统知道后就可以做出相应的对策。
111 6
|
4月前
|
缓存 网络协议 算法
【Linux系统编程】深入剖析:四大IO模型机制与应用(阻塞、非阻塞、多路复用、信号驱动IO 全解读)
在Linux环境下,主要存在四种IO模型,它们分别是阻塞IO(Blocking IO)、非阻塞IO(Non-blocking IO)、IO多路复用(I/O Multiplexing)和异步IO(Asynchronous IO)。下面我将逐一介绍这些模型的定义:
185 1
|
4月前
|
存储 NoSQL Unix
【Linux】进程信号(下)
【Linux】进程信号(下)
35 0
|
4月前
|
安全 Linux Shell
【Linux】进程信号(上)
【Linux】进程信号(上)
42 0