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天前
|
监控 Shell Linux
【Shell 命令集合 系统管理 】⭐⭐⭐Linux 向进程发送信号 kill命令 使用指南
【Shell 命令集合 系统管理 】⭐⭐⭐Linux 向进程发送信号 kill命令 使用指南
34 0
|
6天前
|
Unix Linux
【Linux】详解信号的分类&&如何自定义信号的作用
【Linux】详解信号的分类&&如何自定义信号的作用
|
6天前
|
Unix Linux C语言
|
6天前
|
安全 Linux
【Linux】详解用户态和内核态&&内核中信号被处理的时机&&sigaction信号自定义处理方法
【Linux】详解用户态和内核态&&内核中信号被处理的时机&&sigaction信号自定义处理方法
|
6天前
|
存储 Linux C++
【Linux】详解信号的保存&&信号屏蔽字的设置
【Linux】详解信号的保存&&信号屏蔽字的设置
|
6天前
|
存储 Linux
【Linux】对信号产生的内核级理解
【Linux】对信号产生的内核级理解
|
6天前
|
存储 安全 Linux
【探索Linux】P.18(进程信号 —— 信号捕捉 | 信号处理 | sigaction() )
【探索Linux】P.18(进程信号 —— 信号捕捉 | 信号处理 | sigaction() )
9 0
|
6天前
|
存储 算法 Linux
【探索Linux】P.17(进程信号 —— 信号保存 | 阻塞信号 | sigprocmask() | sigpending() )
【探索Linux】P.17(进程信号 —— 信号保存 | 阻塞信号 | sigprocmask() | sigpending() )
12 0
|
6天前
|
算法 Linux C++
【探索Linux】P.16(进程信号 —— 信号产生 | 信号发送 | 核心转储)
【探索Linux】P.16(进程信号 —— 信号产生 | 信号发送 | 核心转储)
9 0