Linux信号

您所在的位置:网站首页 异步通信包括什么信号传输 Linux信号

Linux信号

2024-07-02 07:28| 来源: 网络整理| 查看: 265

信号 一 、 概念和功能:

信号实际上是一个软中断,用于通知进程发生了某些事,该如何处理。 实际上也归为一类进程间通信方式, 信号的生命周期:信号的产生-信号的注册-信号的阻塞(/屏蔽)-信号的注销-信号的处理

二 、 查看信号:

kill -l ,查看linux下全部信号,可看出信号是由编号和宏组成; 这里写图片描述

kill并不是杀死一个进程,而是为了给某一个指定的进程发送信号。

linux下有62 个信号,分为两类:1-31是非可靠信号(并非实信号),1-31是继承unix而来的,每个信号都对应一个指定事件,非可靠代表这个信号可能会丢失,如果有相同的信号已经注册到这个进程没有被处理,那么接下来的相同信号就会丢掉。 34-64,为可靠信号(实信号)

三 、信号产生方式:

1.硬件中断 (键盘按键中断,ctrl c); 2.硬件异常; (段错误,内存访问错误,core dump,默认发生的信号是11 号SIGSEGV) 3.命令产生:kill 命令 (kill -n pid),默认情况下发送的是信号15SIGTERM 4.软件条件产生:kill函数,raise函数,alarm函数,sigqueue函数

给进程发送信号的接口函数

int kill(pid_t pid,int sig) //向指定进程发送信号 参数:进程id,指定发送给哪个进程 ;信号的编号,指定发送哪个信号 (信号是由编号和宏组成 2 SIGINIT) int raise(int sig) //给当前进程发送信号 int sigqueue(pid_t pid,int sig,union sigval value) //给指定进程发送信号,并且可以传一个参数过去,value是要携带的数据,其类型是union sigval Unsigned int alarm(unsigned int seconds)//在指定second秒后给进程发送信号

这里写图片描述

四 、 core dump 当一个程序要异常终止时,可以选择吧进程用户空间内存数据全部保存到磁盘上,文件名通常是core,这叫做core Dump。 程序异常的时候,会记录一个核心转储文件,在这个文件中记录程序运行数据 。当一个程序奔溃时,这个错误可能只是偶尔发生,这种错误将很难定位,因为不确定到底什么时候才会崩溃,因此这个转储文件(core 文件)就非常重要,它可以帮助我们使用gdb调试 查看,定位错误。 ulimit -c size ,可以设置core dump的大小,例如 ulimit -c 1024 gdb进出程序,运行执行程序(run ),bt,用来查看调用栈。在gdb中使用命令:core-file core.3996()来加载程序的的运行数据,然后就可以定位错误了。 但是程序的核心转储功能是**默认关闭的**,转储文件默认大小为0,因此运行数据中可能有安全性信息,以及文件增多会占用资源 查看文件/改变文件的大小: 信号的注册

将信号记录在进程中,让进程知道有这样一个信号来了。

信号是记录在进程的PCB中 。 信号集合:在PCB中sigset_t 结构体 进程记录一个信号的时候,通过这个结构体的位图来记录

注册:修改进程中PCB中信号pending的位图,添加一个信号的sigqueue结构体节点(pending位图0变1) 注销:修改进程中PCB中信号pending的位图,删除指定信号的sigqueue的结构体节点(pending位图1变0)

这里写图片描述

信号的阻塞与屏蔽

信号阻塞:因为进程PCB 中还有一个结构,这个结构就是block阻塞集合,

在pcb中有 一个pending结构中存储当前接收到的信号,还有一个结构体blocked用于存储 现在有哪些信号要被阻塞。 进程看到了pending集合中都收到了哪些信号,然后就要开始处理这些信号,但在处理这些信号之前,进程先比对一下这些信号有没有存在于blocked集合中,如果存在了(位图为1),意味着现在这个信号不被处理,直到解除阻塞 。

这里写图片描述

信号阻塞接口: 阻塞: int sigprocmask(int how,sigset_t *set,sigset_t *oldset) how:对集合所做的操作,SIG_BLOCK(对set集合,SIG_UNBLOCK,SIG_SETMASK

实现信号阻塞屏蔽 //先定义集合 //将信号添加到集合中:intsigfillset(sigset_t *set); int sigpending(sigseet_t set)//将当前pending集合中的信号取出来放到set中 int sigismember(const sigset_tset,int signum) 判断信号是否在集合中

信号的注销

就是从pending中将要处理的信号移除但分情况: 非可靠信号: 注册的时候,是给sigqueue链表添加一个信号结点,并且将pending集合对应位图置1,当这个信号注册的时候,如果位图已经置1,代表信号已经注册过了,那就不做任何操作,不添加新结点 注销:删除链表中的节点,将对应位图置 0 可靠信号: 注册:是给sigqueue链表添加一个信号节点,不管这个可靠信号是否已经注册过,如果没有注册过,就添加新节点,对应位图置1 注销:删除一个节点,然后查看链表中有没有相同的节点,如果有,那么信号对应的位图 110 依然为1,若果没有相同的节点,代表这个信号全部被处理,因此对应位图置0 111 112 可靠信号因为每次信号到来都会添加新节点,所以不会丢失信号。

#信号处理(信号的递达) 当进程收到一个信号时,就意味着现在有一个重要的事情要处理,因此会打断我们当前的操作,然后去处理这件事

什么时候处理信号呢? 进程从内核态切换到用户态时会去检测是否有信号要处理。

信号的处理方式:

默认处理:系统定义好的处理方式

忽略处理方式:忽略和阻塞完全不同,一个被忽略的信号来了以后就直接丢弃

自定义处理方式:用户自己定义一个的一个处理信号的方式,使操作系统按照定义的这个处理方式来处理这个信号

信号忽略和信号注册的区别,阻塞一个信号后,信号依然会注册在pending集合中,而忽略信号,则信号直接丢弃,不会注册

信号处理方式接口:

sighandler_t signal (int signum, sighandler_t handler) 功能:修改一个信号的处理方式 参数:指定修改哪个信号; 第二个是处理的方式,SIG_IGN(忽略处理),SIG_DFL(默认处理)

int sigaction(int signum,const struct signation *act, struct signation *oldact) 功能:修改信号的处理方式 参数:signum指定修改哪个参数;act是指定的处理动作;oldact 保存信号原来的处理方式 结构体: struct sigaction { void (*sa_handler)(int); //自定义处理方式 void (*sa_sigaction)(int, siginfo_t *, void *); //也是自定义处理方式,可以接收信号携带的参数 sigset_t sa_mask; //在处理信号时要阻塞的其他信号(避免其他信号打扰自定义操作) int sa_flags; //决定用哪个函数作为信号处理接口,默认0则是sa-handler,给定SA_SIGINFO则是sa_sigaction void (*sa_restorer)(void); };

信号的捕捉

针对自定义处理方式,进程捕捉到信号然后进行处理的 过程

进程是从内核态切换到用户态时,需要判断是否有信号要处理,然后返回用户态去自定义处理,在返回内核,在返回用户态 如何实现从用户态到内存态的切换?中断,异常,系统调用

可重入函数

可重入函数:某个函数调用的时候,如果中间操作被打断,在其他地方有重复多次调用,不影响运行结果(对其他地方的调用产生影响),这个函数就叫可重入函数 不可重入函数:多次调用影响结果。

可重入函数的特点:操作了一些公共数据

竞态条件:

如果我们的某个操作不是一个原子操作,那么意味着这个操作有可能被打断然后去做其他的事情,这时做其他事情可能产生一些逻辑问题

int sigsuspend(const sigsey_t *mask) //集合了临时阻塞指定信号,并陷入阻塞等待的一个原子操作 功能:临时使用mask中的信号替换阻塞结合blocked中的信号,然后进入阻塞等待,唤醒后还原。 也就是说临时替换阻塞信号,进入休眠,唤醒时 ,在将原来的阻塞信号替换回

自己写的sleep为例,讲解竞态条件,说的是alarm函数和pause函数间如果被打断去干其他事情,可能造成pause永久阻塞

volatile:c语言的关键字,保证内存的可见性。每次处理这个被volatile修饰的变量时,都会从内存中重新加载变量的值都内存器中

因为程序在优化的时候,如果一个变量使用的频率很高的话(比如全局变量)那么,这个变量有可能被优化为只向内存器加载一次,往后直接使用寄存器中保存的值。 而不关心它在内存里的值,因此可能会造成一些逻辑错误

SIGCHILD 信号 自定义处理,循环的原因是对子进程资源随退随回收,且大致不影响逻辑。 信号是会打断进程的阻塞操作,唤醒正在休眠的进程



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3