总览 信号总览 信号分了三个章节进行介绍. 本章介绍基础理论,简单但是非常重要且有必要. 本章总览 各种信号和使用场景. 信号源:内核,进程或自己(系统调用). 信号处理:内核默认,开发自定义(自定义,忽略,恢复默认),忽略。 信号屏蔽:屏蔽的信号被挂起排队,等到取消屏蔽的时候处理. 信号等待:暂停执行进程,等待信号的到来. 概念总览 使用 什么是信号 进程间或进程与内核间的通讯方式. 某进程收到信号,表示有与之相关的事情发生,需要立即处理或等会儿处理,和进程的处理策略有关. 软件中断 和硬件中断打断处理器一样,软件中断打断进程的执行,让其执行代码进行响应. 信号源 拥有权限的信号可以发送信号给其他进程. 常见:bash通过kill指令发送信号给其他进程. 进程自己可以发送给自己或自己的某个线程. 信号源一般都是内核产生. 作用 可用作进程间同步机制,甚至进程间交流IPC. 案例分析 硬件错误 硬件检测错误,由内核转发. 如:地址翻译硬件检测无映射,内核转发SIGSEGV;或者处理器执行除0操作,内核转发SIGFPE. 用户输入 中断将特殊字符产生的信号. ctrl-c中断进程SIGINT. ctrl-z中断并挂到后台SIGHUP. 内核通知事件需要处理 IO多路复用的信号驱动读写. 终端窗口发生变化. 定时器超时. 处理器CPU使用时间超限. 子进程死亡. 信号定义 实际 一个整数. 宏定义以SIGxxxx的格式声明. 开发 不同平台值代表信号不一样,所以使用宏定义别名,而不是具体数字. 两类信号 实时信号 传统的信号,或者标准信号. 一般用于内核提示进程. 使用区间1-31. 实时信号 详细介绍 信号处理 生成 发送,并添加到进程描述符中,等待处理. 处理 一般是被时钟中断了之后,切换上下文,退出内核空间前检测,如果有信号需要处理就会处理. 或者是如果正在执行立即处理. 信号屏蔽 信号处理可能会打断正在使用内核栈的系统调用,导致系统调用失败. 为了避免这种情况:可以屏蔽某些信号,等到后面方便的时候取消阻塞,处理对应时间. 屏蔽的信号阻塞排队,直到取消阻塞. 进程处理方式 忽略 内核丢弃,甚至进程都不知道这个信号. 终止进程 进程被杀死. 进程正常死亡是exit,异常则是直接内核干掉,不用通知进程任何事情. 生成core并终止进程 会生成杀死那一刻的内存信息.或者说是这个时刻的虚拟内存空间数据. 保留了大部分的数据,用作调试排查错误. 暂停 进程停止执行,一般是gdb调试 继续 进程恢复执行,一般是gdb调试。 如果之前没有处于停止状态则忽略. 开发者可自定义 默认 一般用于修改后恢复原来的操作. 忽略 一般用于屏蔽某些无用或不感兴趣的信号. 自定义函数 函数执行,在内核中执行,和普通函数一样. 一般用来专门响应某个信号,执行某一些任务. 这类信号叫做被处理或捕获. 自定义局限 局限 不能修改为内核的默认行为中的terminate,dump core. 但是可以是忽略. 也就是说自定义也是有局限性的. 简介实现 虽然无法直接修改行为,但是可以通过间接的方式修改. 在信号响应函数中执行对应的函数来发起另一个信号,以此来间接的达到同样的效果. 进程信号状态查看 位置 /proc/pid/status 内容 包含了各种各样的信号信息,以掩码的形式表示。 以16进制表示. 关联字段 SigPnd线程挂起的信号. ShdPnd进程挂起的信号. SigBlk进程屏蔽的信号. SigIgn进程忽略的信号. SigCgt进程捕获的信号.(用户自定义) 信号类型和默认行为 信号与宏 理论 使用的常规信号是1-31 实际 名字超过32,不同名字对应的值相同. 或者是不同的平台支持的不同. 信号介绍 SIGABRT 原因 进程中调用abrt()函数. 结果 默认生成core文件. SIGALRM 原因 内核中通过alarm,setitimer设置的的实时定时器超时. 介绍 now + expire+time这种时钟. SIGBUS 原因 内存访问错误. 案例一 mmap映射预留空间. 即4k的页面中创建了8k的空间用于映射,文件大小2k,这是只有第一块中的前2k存在文件映射,3-4可以访问,但是访问5-8这个不存在任何映射的空间就是错误. SIGCHLD,SIGCLD 原因 父进程的某个子进程死亡.exit的方式死亡. 使用 这种一般是通知父进程通过wait函数获取子进程的死亡信息,并释放最后的空间. SIGCONT 使用 发送信号给暂停状态的进程。 处理 处于暂停恢复,不是就忽略. 执行一些恢复的代码.一般是用户自定义. 拓展 后面其他章节有详细介绍 SIGFPE 原因 FPE:Floating-pointe exception算数计算错误,比如:除0. 分析 虽然是浮点,但是整数仍然使用. 实际上这个信号的产生主要和处理器架构和对应的CPU控制寄存器的实现. 举例 x86-32中,虽生成SIGFPE,但是师傅处理根据内核配置FE_DIVBYZERO,即是否允许除0. 允许就生成FPE,不允许就得到的结果就是无限大IEEE标准. SIGHUP 案例一 终端客户端与服务器的连接中断,内核就会发送信号给服务器程序,停止执行.或挂起. 后面章节分析. 案例二 使用这个信号发送给守护进程(init,httpd,inetd),让其重新读取配置,重新初始化执行. 系统也是通过这个信号告知守护来重启 SIGILL 原因 错误执行机器指令. SIGINFO 平台 Linux类似SIGPWR. BSD源于ctrl T BSD原因 获取正在执行的前台程序的信息. SIGINT 原因 用户输入ctrl c,中段驱动程序发送对应信号给前台进程组. 响应