【linux】信号(上)

守听  金牌会员 | 2024-11-3 19:15:09 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 811|帖子 811|积分 2433

 

1. 认识信号

信号是进程之间变乱异步通知的一种方式,属于软停止

留意:

  • 进程一定要有识别和处置惩罚信号的能力(即使信号没有产生,也要具备处置惩罚信号的能力,并且处置惩罚信号的能力,属于进程内置的一部分)
  • 当一个进程收到了一个信号的时候,不一定会立刻处置惩罚这个信号
  • 一个进程从信号产生,到信号被处置惩罚的这个阶段,会偶然间窗口,即进程具有临时生存哪些信号已经发生的能力
2. 信号处置惩罚常见方式概览

处置惩罚信号分三种


  • 忽略此信号。
  • 执行该信号的默认处置惩罚动作(进程内置了,每一种信号有差异的处置惩罚方式)
  • 提供一个信号处置惩罚函数,要求内核在处置惩罚该信号时切换到用户态执行这个处置惩罚函数,这种方式称为捕捉
(Catch)一个信号,(即自界说动作,自己规定哪一种信号对应哪一种处置惩罚方式)

3. 技术应用角度的信号

1. 用户输入下令,在Shell下启动一个前台进程
用户按下Ctrl+C ,这个键盘输入产生一个硬件停止,被OS获取,表明成信号,发送给目的前台进程
前台进程因为收到信号,进而引起进程退出
   画图表明
  
  

  
  留意:

  • linux 中,一次登岸,一个终端,一样平常会配上一个 bash,每一个登录都只允许有一个前台进程(键盘上的输入,都是发送给前台进程的),可以允许有多个背景进程
  • Ctrl+C 被表明成2号信号
  • Ctrl-C 产生的信号只能发给前台进程。一个下令后面加个&可以放到背景运行,这样Shell不必等待进程结束就可以接受新的下令,启动新的进程

4. 系统界说的信号列表

   

  • kill -l
  
  

  留意:
  1 ~ 31 : 平凡信号(一样平常以位图的情势储存在对应的进程PCB中,tast_struct 中有 signal ,此中比特位的 0 ,1 表现是否收到信号,比特位的位置(第几个)表现信号编号,所谓的发送信号就是更改对应进程信号位图的比特位)
  这里是存在一些问题,如:信号可以发送很多次,但是迟迟没有处置惩罚信号,导致处置惩罚次数和发送信号次数不对等(处置惩罚次数可能会减少)
  34 ~ 64 : 实时信号(接受信号后,立刻处置惩罚信号,一样平常以链表的情势存储,以是发送信号次数和处置惩罚次数是一样的)
  

  • man 7 signal

5. 修改特定的进程对于信号处置惩罚的动作

   signal函数
  功能:修改特定的进程对于信号处置惩罚的动作
  typedef void (*sighandler_t)(int);
  
  原型:
  sighandler_t signal(int signum,sighandler_t handler);
  参数:
  signum:信号编号(可以通过查察信号列表得到)
  handler:自界说处置惩罚方法
    代码
  
  

  
  

  
  留意:
signal函数只需要调用一次,往后都有效,且只有产生信号的时候,才会执行对应的方法

6. 信号的产生方式

1. 键盘组合键
如:Ctrl + C --- 2号信号 Ctrl + \ ---- 3号信号
2. kill 下令
kill -信号编号 + 进程pid
3. 系统调用


  • kill函数


  • raise函数
  • abort函数
4. 软件产生信号
如: 管道发送读端关闭,写段正常,此时会产生信号,杀死进程


7. 产生信号

(一)通过终端按键产生信号



留意:
Term 和 Core 都是会退出进程

Core Dump


  • Core Dump概念: 当一个进程要异常停止时,可以选择把进程的用户空间内存数据全部生存到磁盘上,文件名通常是core,这叫做Core Dump。(即 假如打开系统的 core dump 功能,一旦进程异常,OS 会将进程在内存中的运行信息,转储到进程的当前目录(磁盘)形成 core.pid 文件)
  • 一个进程允许默认是不允许产生core文件的(因为core文件中可能包罗用户密码等敏感信息,不安全)
  • 开发调试阶段可以用ulimit下令改变这个限定,允许 产生core文件。 首先用ulimit下令改变Shell进程的Resource Limit,允许core文件最大为1024K: 如 ulimit -c 1024

   
  
  

  写一个死循环,终端输入Ctrl + \ ,得到如下:
  
  

  
  留意:
进程异常停止通常是因为有Bug,比如非法内存访问导致段错误, 过后可以用调试器检查core文件以查清错误原因,这叫做过后调
(二)调用系统函数向进程发信号



  • kill函数
int kill(pid_t pid,int sig);
pid : 进程pid ; sig : 信号编号


  • raise函数
int raise(int sig);


  • abort函数
void abort(void)
发送6号信号,且不管是否是否对6号自界说处置惩罚动作,都一定会退出进程

3. 由软件条件产生信号
这里主要介绍alarm 函数
   原型:
  unsigned int alarm(unsigned int seconds);
  
  返回值:
  因为 alarm 可以被多次调用,返回值是上一次alarm函数调用剩下的秒数(有可能上一个alarm函数时间没到,又被调用了)
  
留意:
调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当进步程发SIGALRM信号, 该信号的默认处置惩罚动作是停止当进步程

(三)硬件异常产生信号

硬件异常被硬件以某种方式被硬件检测到并通知内核,然后内核向当进步程发送适当的信号
(如当进步程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常表明 为SIGFPE信号发送给进程。又如当进步程访问了非法内存地址,MMU会产生异常,内核将这个异常表明为SIGSEGV信号发送给进程)



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

守听

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表