[Linux][进程信号][一][信号基础][如何产生信号]详细解读

目录


0.前言预备

1.系统定义的信号列表

  • **[1, 31]:**普通信号

  • **[34, 64]:**实时信号

  • 这些信号在什么条件下产生,默认的处理动作是什么,可以通过 man 7 signal 查看

2.核心转储 -- Core Dump

  • 当一个进程要异常终止时,可以选择把当前进程在内存中的相关核心数据转存到磁盘上,文件名通常是core,这叫做Core Dump
  • 进程异常终止通常是因为有Bug,事后可以用调试器检查core文件以查清错误原因,这叫做Post-mortem Debug(事后调试)
    • 使用:core -file core.pid
  • 默认是不允许产生core文件的,因为core文件中可能包含用户密码等敏感信息,不安全
    • 一个进程允许产生多大的core文件取决于进程的Resource Limit(这个信息保存在PCB中)
    • 在开发调试阶段可以用ulimit 命令改变这个限制,允许产生core文件
      • ulimit -a
      • ulimit -c
      • 当前bash会话有效

1.信号基础

1.信号概念

  • 信号是进程之间事件异步通知的一种方式,属于软中断
    • 本质是一种通知机制
  • 理解信号思路
    • 进程要处理信号,必须具备信号"识别"能力(看到 + 处理动作)
    • 进程为什么能够"识别"信号?
      • 程序员通过代码提前设置好的
    • 信号产生是随机的,进程可能正在忙自己的事情
      • 信号可能后续被处理,不一定是立即处理
    • 信号会临时的记录下对应的信号,方便后续进行处理
      • 何时处理?
        • 合适的时候
    • 一般而言,信号的产生相对于进程而言是异步的

2.信号处理方式概览

  • 执行该信号的默认处理动作
  • 忽略此信号
  • 自定义动作(捕捉信号)
    • 提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数
  • 信号捕捉初识
    • **功能:**捕获特定的信号,执行自定的方法
    • 原型:sighandler_t signal(int signum, sighandler_t handler);
    • 参数:
      • **signum:**要捕获的信号
      • **handler:**函数指针,要执行的自定方法
    • 返回值:
      • 不在乎
    • 注意:
      • signal函数,仅仅是修改进程对特性信号的后续处理动作,不是直接调用对应的处理动作
      • 如果后续没有任何SIGNAL信号产生,handler永远不会被调用

3.理解信号如何被保存

  • 需要解决两个问题 --> 什么信号?是否产生?
  • 进程PCB内部保存了**信号位图**字段
    • 第几个比特位表示什么信号
    • 01表示是否产生信号

4.信号发送的本质

  • 信号位图在task_struct --> task_struct内核数据结构 --> OS掌控
  • 信号发送的本质:OS向目标进程写信号,OS直接修改PCB中的指定的位图结构,完成"发送"信号的过程

2.如何产生信号?

1.终端按键产生信号

  • 键盘的工作方式是通过中断方式 进行的
    • 便可以**识别组合键,**如Ctrl + c
  • OS解释组合键 --> 查找进程列表 --> 找到前台运行的进程 --> OS写入对应的信号到进程内部的位图结构中

2.系统调用接口

1.kill()

  • **功能:**给指定的进程发送指定的信号
  • 原型:int kill(pid_t pid, int sig);

2.raise()

  • **功能:**给当前进程发送指定的信号 --> 自己给自己发信号
  • 原型:int raise(int sig);

3.abort()

  • **功能:通常用来终止进程,发送SIGABRT(6)**信号
  • 原型:void abort(void);

4.如何理解?

  • 用户调用系统接口 --> 执行OS对应的系统调用代码 --> OS提取参数,或者设置特定的数值 --> OS****向目标进程写信号 --> 修改对应进程的信号标记位 --> 进程后续会处理信号 --> 执行对应的处理动作

3.由软件条件产生信号

  • 如:管道 读端不光不读,而且还关闭了,写端一直在写,会发生什么问题?
    • 写没有意义,OS会自动终止对应的写端进程,通过发送信号(SIGPIPE)的方式
  • 如:alarm() && SIGALRM
    • 功能:
      • 设定一个闹钟,告诉内核在seconds秒之后给当前进程发SIGALRM信号,该信号的默认处理动作是终止当前进程
      • 闹钟一旦触发,就自动移除了
  • 原型:unsigned int alarm(unsigned int seconds);
  • 返回值:
    • 0
    • 以前设定的闹钟时间还余下的秒数
  • 如何理解?
    • OS先识别到某种软件条件触发或不满足某条件 --> OS构建信号,发送给指定的进程

4.硬件异常产生信号

  • 硬件异常被硬件以某种方式被硬件检测到并通知内核,然后内核向当前进程发送适当的信号
    • 例如:当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释为SIGFPE信号发送给进程
    • 例如:当前进程访问了非法内存地址,,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程
  • 由此看出,在C/C++中,除零,内存越界等异常,在系统层面上,是被当成信号处理的

5.总结

  • 所有的信号,有他的来源,但最终全部都是被OS识别,解释,并发送的
相关推荐
乙己4073 小时前
计算机网络——网络层
运维·服务器·计算机网络
飞行的俊哥3 小时前
Linux 内核学习 3b - 和copilot 讨论pci设备的物理地址在内核空间和用户空间映射到虚拟地址的区别
linux·驱动开发·copilot
hunter2062065 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb5 小时前
web服务器 网站部署的架构
服务器·前端·架构
不会飞的小龙人5 小时前
Docker Compose创建镜像服务
linux·运维·docker·容器·镜像
不会飞的小龙人6 小时前
Docker基础安装与使用
linux·运维·docker·容器
白粥行7 小时前
linux-ubuntu学习笔记碎记
linux·ubuntu
果果开发ggdoc.cn7 小时前
WordPress免费证书插件
服务器·https·ssl
jerry-897 小时前
通过配置核查,CentOS操作系统当前无多余的、过期的账户;但CentOS操作系统存在共享账户r***t
linux
小歆8848 小时前
100%全国产化时钟服务器、全国产化校时服务器、全国产化授时服务器
运维·服务器