本篇介绍一些Linux信号处理相关内容.

1. 信号的概念

信号是进程间的一种异步通信机制, 是软件层面对中断机制的模拟.

中断就是打断正在执行的程序, 跳转到另一段程序区执行, 执行完毕后返回被打断的程序继

续执行.

linux 系统中支持的信号 1~64, unix 系统中支持的信号 1~48

kill -l : 列出系统中支持的所有信号

宏的名称以 SIG 开头, 使用宏可以避免不同系统对信号的编码差异

信号的本质就是一个数字, 编程时不建议直接使用该数字, 而是使用对应的宏, 这样可移植性高.

在 linux 系统中, 1~31 是不可靠信号, 早期信号, 不支持排队,34~64 是可靠信号, 支持排队, 不会丢失.

2. 信号的何产生

2.1 键盘发送, 只能产生部分信号

ctrl + c ---> 发送信号 SIGINT 2

ctrl + ---> 发送信号 SIGQUIT 3

2.2 程序出错, 也是只能产生部分信号段错误

段错误 ---> SIGSEGV

总线错误 ---> SIGIO

子进程结束 ---> SIGCHLD

2.3 kill 命令 ( 可以发所有的信号), 给指定的进程法 1~64 的信号

kill + 信号 + 进程PID ---> kill -9 1818

2.4 系统函数 kill 函数

int kill (pid_t pid, int sig);

3. 进程处理信号的方式

(1) 默认处理, 系统提供, 多半是退出进程, 会导致进程非正常退出

(2) 忽略信号, 信号不被处理

(3) 自定义处理函数, 信号按照程序员的代码进行处理

注意:

1) 有些信号是不能被自定义或者忽略的, 比如信号 9 kill -9

2) 进程可以给其他的进程法信号, 但是只能给本用户的进程发信号, root 用户可以给所有 的用户进程发信号

4. 信号相关的 API

4.1 signal 函数

signal函数的作用有两个, 一是设置信号默认处理方式,二是注册一个信号处理函数

typedef void ( *sighandler_t ) ( int );sighandler_t signal ( int signum, sighandler_t handler ); signum: 信号对应的编号, 或者宏 handler: 可以有三个类型取值 (1) SIG_DFL 信号恢复成默认方式 (2) SIG_IGN 忽略信号 ignore (3) 自定义函数的地址 函数指针  typedef void ( *sighandler_t ) ( int ); void (*)(int) 是函数指针类型, 指一个返回值为 void, 参数为 int 类型的函数指针类型 

4.2 进程中信号的发送

kill(重点掌握) / alarm / raise / sigqueue

(1) kill() 函数

作用: 用于向任何进程组或进程发送信号

int kill (pid_t pid, int sig)pid : 指定被哪个或者哪些进程发送信号 pid>0, 给 pid 对应的进程发送信号 pid=0, 本组所有进程发送信号 pid=-1, 给所有由权限的进程发送信号 pid

注意: 不能给任意的进程发信号, 例如给 1 号进程发送 SIGINT 信号是不可要的, 权限不够

(2) alarm() 函数

作用: seconds 秒后给当前进程发送一个 SIGALARM 信号

unsigned int alarm ( unsigned int seconds )seconds : 设置多少秒之后发送SIGALARM信号返回值 : 如果在seconds秒内再次调用了alarm函数设置了新的闹钟,则后面定时器的设置将覆盖前面的设置,即之前设置的秒数被新的闹钟时间取代;当参数seconds为0时,之前设置的定时器闹钟将被取消,并将剩下的时间返回

(3) raise()函数

作用: 用于向调用进程发送信号

int raise ( int sig );sig : 准备发送的信号代码返回值 : 成功执行时返回0,失败返回非0

总结:

int raise(int signum) 等价于 kill(getpid(),signum);

alarm(seconds) 等价于 sleep(seconds) + kill(getpid(),SIGALRM)

5. 信号的屏蔽

5.1 信号屏蔽信号的原因

信号的产生有时候是无法确定和控制的, 可以使用信号屏蔽技术让信号的处理时间延后, 信号屏蔽主要应用于关键代码的执阶段

信号屏蔽不是阻止信号的到来, 信号是无法阻止的, 而是将信号的处理延后, 待关键代码执行完毕后再解除信号的屏蔽

5.2 信号屏蔽函数

sigprocmask() 函数可以完成信号的屏蔽和解除信号的屏蔽

int sigprocmask (int how, const sigset_t *set, sigset_t *oldset )how : 用于指定信号修改的方式,可能选择有三种 SIG_BLOCK : 将set所指向的信号集中包含的信号加到当前的信号掩码中,即信号掩码和set信号集进行或操作 SIG_UNBLOCK : 将set所指向的信号集中包含的信号从当前的信号掩码中删除,即信号掩码和set进行与操作 SIG_SETMASK : 将set的值设定为新的进程信号掩码,即set对信号掩码进行了赋值操作set : 为指向信号集的指针,在此专指新设的信号集,如果仅想读取现在的屏蔽值,可将其置为NULLoldset : 传出参数, 也是指向信号集的指针,在此存放原来的信号集。可用来检测信号掩码中存在什么信号返回说明 : 成功执行时,返回0。失败返回-1,errno被设为EINVAL

5.3 信号集操作函数

(1) 将信号集合 set 中所有信号位置 1

int sigfillset(&set);

(2) 将信号集合 set 中所有信号为清 0

int sigemptyset(&set);

(3) 将信号集合 set 中与 signum 对应的 bit 置 1

int sigaddset(&set,signum);

(4) 将信号集合 set 中与 signum 对应的 bit 清 0

int sigdelset(&set,signum);

(5) 测试 signum 是否为 set 中的一个成员

int sigismember(const &set,signum);

如果是其中一个成员返回 1, 否则返回 0

(6) 获取被屏蔽的信号, 就是在执行关键代码期间发送过来的信号

int sigpending(&set);

引申:

1. 主进程中调用了 signal(SIGINT,...) ,然后执行 fork(), 那么子进程中在怎样处理 SIGINT 信号

子进程继承了父进程的信号处理策略

2. 如果问题 1 中换成 vfork 会怎样

vfork 创建子的子进程不会继承父进程的信号处理策略

linux 程序收到sigsegv信号_Linux基础知识(五)相关推荐

  1. linux 程序收到sigsegv信号_linux下定位多线程内存越界问题实践总结

    最近定位了在一个多线程服务器程序(OceanBase MergeServer)中,一个线程非法篡改另一个线程的内存而导致程序core掉的问题.定位这个问题历经曲折,尝试了各种内存调试的办法.往往感觉就 ...

  2. linux 程序收到sigsegv信号_信号

    当其他方式不起作用时(例如标准输入被冻结),信号是提供低优先级信息和用户与其程序交互的便捷方式.它们允许程序在事件发生时清理或执行操作.有时,程序可以选择忽略受支持的事件.由于处理信号的方式,制作一个 ...

  3. 编程语言基础c语言第5版讲解,《程序设计基础》C语言基础知识讲解.ppt

    <<程序设计基础>C语言基础知识讲解.ppt>由会员分享,可在线阅读,更多相关<<程序设计基础>C语言基础知识讲解.ppt(54页珍藏版)>请在人人文库 ...

  4. Linux之(5)账户和shell基础知识

    Linux之(5)账户和shell基础知识 Author:onceday date:2022年8月23日 漫漫长路,而今才刚刚开始- 本内容主要收集整理于: <Linux命令行与shell脚本编 ...

  5. git 分支复制_Git基础知识(五)

    Git基础知识(五) 分支 都说Git的分支是它的必杀技特性,由于没有接触过太多的版本管理工具,就使用过的SVN来说,两者真的差别巨大.SVN创建一个分支,需要将内容复制一遍!这个时间真的是非常的漫长 ...

  6. JavaSE基础知识(五)--面向对象代码实现初步(实现一个简单的类类型代码)

    Java SE 是什么,包括哪些内容(五)? 本文内容参考自Java8标准 一.面向对象(代码实现): 首先,在这里我需要说明一个根本性的问题:实际上,面向对象编程包括了两部分,一个是你的编程思想,一 ...

  7. 如何在linux程序中捕获异常信号

    最近在搞一个linux项目,碰巧遇到了一个段错误的问题.经过一段时间的排查和学习,对段错误这个概念有了些许的理解,现总结如下: 一.什么是段错误 一句话来说,段错误是指访问的内存超出了系统给这个程序所 ...

  8. xshell 无法定位输入点_linux基础知识个人总结

    linux基础知识个人总结 第一章: 1. Linux发展史略,有代表性的Linux发行版:Suse.slackware.ubuntu.RedHat.CentOS 2. GNU是Richard Sta ...

  9. java程序设计基础知识点_Java编程语言基础知识的要点

    原标题:Java编程语言基础知识的要点 很多Java编程初学者在刚接触Java语言程序的时候,不知道该学习掌握哪些必要的基础知识.下面就说说Java零基础学习Java编程语言基础知识的几个要点.希望能 ...

最新文章

  1. XML配置文件的命名空间与Spring配置文件中的头
  2. 如何创建文件并用Java写入文件?
  3. JDK 1.5 环境变量的配置
  4. mysql附加服务器失败_今天,启动MySQL服务器失败,
  5. PolarMask:单阶段实例分割框架,FCOS进阶!
  6. '[linux下tomcat 配置
  7. 混凝土墙开洞_易县混凝土剪力墙切割常见问题
  8. 动力环境监控系统论文_机房动力环境监控系统方案
  9. jquery 下拉选择框/复选框常用操作
  10. 看懂这些代码,我哭着笑了
  11. VB:设定 MsgBox 在若干时间之后若无回应则自动关闭
  12. stm32呼吸灯c语言程序,STM32 呼吸灯程序请教
  13. Excel 如何将图片URL 显示为图片
  14. Linux 如何查看文件夹的大小
  15. 为Exynos4412移植2022版U-Boot(一)步骤及其原理分析
  16. 全国哀悼日 网站灰黑色CSS滤镜代码
  17. 中国医科大计算机在线作业答案,16秋中国医科大学《计算机应用基础(中专起点大专)》在线作业标准答案包100分...
  18. 网页设计常用色彩搭配表 - 配色表
  19. 三、大数据存储——HBase
  20. 川内计算机专业,川内大学计算机专业排名

热门文章

  1. A Hierarchical Reinforced Sequence Operation Method for Unsupervised Text Style Transfer
  2. MC-GAN:Multi-Content GAN for Few-Shot Font Style Transfer
  3. 8086寄存器的配合使用
  4. 从应用上看计算机将向那个方向发展,(2)2019年6月一级Ms Office试题
  5. 斐波那契数(动态规划和递归)
  6. python - super 寻找继承关系
  7. 【node】node连接mongodb操作数据库
  8. 【题解】ZJOI2017仙人掌
  9. Spring、SpringMVC和Springboot的区别
  10. dev 域名与 Chrome