linux c之信号signal处理机制

最近同事的程序设计过程中用到了Linux的signal机制,从而引发了我对Linux中signal机制的思考。Signal机制在Linux中是一个非常常用的进程间通信机制,很多人在使用的时候不会考虑该机制是具体如何实现的。signal机制可以被理解成进程的软中断,因此,在实时性方面还是相对比较高的。Linux中signal机制的模型可以采用下图进行描述。

个进程都会采用一个进程控制块对其进行描述,进程控制块中设计了一个signal的位图信息,其中的每位与具体的signal相对应,这与中断机制是保持一致的。当系统中一个进程A通过signal系统调用向进程B发送signal时,设置进程B的对应signal位图,类似于触发了signal对应中断。发送signal只是“中断”触发的一个过程,具体执行会在两个阶段发生:

1、  system call返回。进程B由于调用了system call后,从内核返回用户态时需要检查他拥有的signal位图信息表,此时是一个执行点。

2、  中断返回。进程被系统中断打断之后,系统将CPU交给进程时,需要检查即将执行进程所拥有的signal位图信息表,此时也是一个执行点。

 

综上所述,signal的执行点可以理解成从内核态返回用户态时,在返回时,如果发现待执行进程存在被触发的signal,那么在离开内核态之后(也就是将CPU切换到用户模式),执行用户进程为该signal绑定的signal处理函数,从这一点上看,signal处理函数是在用户进程上下文中执行的。当执行完signal处理函数之后,再返回到用户进程被中断或者system call(软中断或者指令陷阱)打断的地方。

 

       Signal机制实现的比较灵活,用户进程由于中断或者system call陷入内核之后,将断点信息都保存到了堆栈中,在内核返回用户态时,如果存在被触发的signal,那么直接将待执行的signal处理函数push到堆栈中,在CPU切换到用户模式之后,直接pop堆栈就可以执行signal处理函数并且返回到用户进程了。Signal处理函数应用了进程上下文,并且应用实际的中断模拟了进程的软中断过程。

 

最近写程序,各种bug各种错,有一回程序莫名退出,没报错,也没产生日志和core文件,貌似正常退出一样。

但又不是在程序全部走完后退出,中途莫名退出,这就叫我想到了signal,应该是某些函数错误后发送kill信号给主进程,然后退出。

现在总结下signal各种类型:

Signal
Description
SIGABRT
由调用abort函数产生,进程非正常退出
SIGALRM
用alarm函数设置的timer超时或setitimer函数设置的interval timer超时
SIGBUS
某种特定的硬件异常,通常由内存访问引起
SIGCANCEL
由Solaris Thread Library内部使用,通常不会使用
SIGCHLD
进程Terminate或Stop的时候,SIGCHLD会发送给它的父进程。缺省情况下该Signal会被忽略
SIGCONT
当被stop的进程恢复运行的时候,自动发送
SIGEMT
和实现相关的硬件异常
SIGFPE
数学相关的异常,如被0除,浮点溢出,等等
SIGFREEZE
Solaris专用,Hiberate或者Suspended时候发送
SIGHUP
发送给具有Terminal的Controlling Process,当terminal被disconnect时候发送
SIGILL
非法指令异常
SIGINFO
BSD signal。由Status Key产生,通常是CTRL+T。发送给所有Foreground Group的进程
SIGINT
由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程
SIGIO
异步IO事件
SIGIOT
实现相关的硬件异常,一般对应SIGABRT
SIGKILL
无法处理和忽略。中止某个进程
SIGLWP
由Solaris Thread Libray内部使用
SIGPIPE
在reader中止之后写Pipe的时候发送
SIGPOLL
当某个事件发送给Pollable Device的时候发送
SIGPROF
Setitimer指定的Profiling Interval Timer所产生
SIGPWR
和系统相关。和UPS相关。
SIGQUIT
输入Quit Key的时候(CTRL+\)发送给所有Foreground Group的进程
SIGSEGV
非法内存访问
SIGSTKFLT
Linux专用,数学协处理器的栈异常
SIGSTOP
中止进程。无法处理和忽略。
SIGSYS
非法系统调用
SIGTERM
请求中止进程,kill命令缺省发送
SIGTHAW
Solaris专用,从Suspend恢复时候发送
SIGTRAP
实现相关的硬件异常。一般是调试异常
SIGTSTP
Suspend Key,一般是Ctrl+Z。发送给所有Foreground Group的进程
SIGTTIN
当Background Group的进程尝试读取Terminal的时候发送
SIGTTOU
当Background Group的进程尝试写Terminal的时候发送
SIGURG
当out-of-band data接收的时候可能发送
SIGUSR1
用户自定义signal 1
SIGUSR2
用户自定义signal 2
SIGVTALRM
setitimer函数设置的Virtual Interval Timer超时的时候
SIGWAITING
Solaris Thread Library内部实现专用
SIGWINCH
当Terminal的窗口大小改变的时候,发送给Foreground Group的所有进程
SIGXCPU
当CPU时间限制超时的时候
SIGXFSZ
进程超过文件大小限制
SIGXRES
Solaris专用,进程超过资源限制的时候发送

signal对应的值:

POSIX.1中列出的信号:

SIGHUP 1 A 终端挂起或者控制进程终止 
SIGINT 2 A 键盘中断(如break键被按下) 
SIGQUIT 3 C 键盘的退出键被按下 
SIGILL 4 C 非法指令 
SIGABRT 6 C 由abort(3)发出的退出指令 
SIGFPE 8 C 浮点异常 
SIGKILL 9 AEF Kill信号 
SIGSEGV 11 C 无效的内存引用 
SIGPIPE 13 A 管道破裂: 写一个没有读端口的管道 
SIGALRM 14 A 由alarm(2)发出的信号 
SIGTERM 15 A 终止信号 
SIGUSR1 30,10,16 A 用户自定义信号1 
SIGUSR2 31,12,17 A 用户自定义信号2 
SIGCHLD 20,17,18 B 子进程结束信号 
SIGCONT 19,18,25 进程继续(曾被停止的进程) 
SIGSTOP 17,19,23 DEF 终止进程 
SIGTSTP 18,20,24 D 控制终端(tty)上按下停止键 
SIGTTIN 21,21,26 D 后台进程企图从控制终端读 
SIGTTOU 22,22,27 D 后台进程企图从控制终端写 

没在POSIX.1中列出,而在SUSv2列出

SIGBUS 10,7,10 C 总线错误(错误的内存访问) 
SIGPOLL A Sys V定义的Pollable事件,与SIGIO同义 
SIGPROF 27,27,29 A Profiling定时器到 
SIGSYS 12,-,12 C 无效的系统调用 (SVID) 
SIGTRAP 5 C 跟踪/断点捕获 
SIGURG 16,23,21 B Socket出现紧急条件(4.2 BSD) 
SIGVTALRM 26,26,28 A 实际时间报警时钟信号(4.2 BSD) 
SIGXCPU 24,24,30 C 超出设定的CPU时间限制(4.2 BSD) 
SIGXFSZ 25,25,31 C 超出设定的文件大小限制(4.2 BSD) 

(对于SIGSYS,SIGXCPU,SIGXFSZ,以及某些机器体系结构下的SIGBUS,Linux缺省的动作是A (terminate),SUSv2 是C (terminate and dump core))。 

下面是其它的一些信号 

信号 值 处理动作 发出信号的原因 
---------------------------------------------------------------------- 
SIGIOT 6 C IO捕获指令,与SIGABRT同义 
SIGEMT 7,-,7 
SIGSTKFLT -,16,- A 协处理器堆栈错误 
SIGIO 23,29,22 A 某I/O操作现在可以进行了(4.2 BSD) 
SIGCLD -,-,18 A 与SIGCHLD同义 
SIGPWR 29,30,19 A 电源故障(System V) 
SIGINFO 29,-,- A 与SIGPWR同义 
SIGLOST -,-,- A 文件锁丢失 
SIGWINCH 28,28,20 B 窗口大小改变(4.3 BSD, Sun) 
SIGUNUSED -,31,- A 未使用的信号(will be SIGSYS) 

(在这里,- 表示信号没有实现;有三个值给出的含义为,第一个值通常在Alpha和Sparc上有效,中间的值对应i386和ppc以及sh,最后一个值对应mips。信号29在Alpha上为SIGINFO / SIGPWR ,在Sparc上为SIGLOST。) 

处理动作一项中的字母含义如下 
A 缺省的动作是终止进程 
B 缺省的动作是忽略此信号 
C 缺省的动作是终止进程并进行内核映像转储(dump core) 
D 缺省的动作是停止进程 
E 信号不能被捕获 
F 信号不能被忽略


代码测试

#include<stdio.h>  
#include<signal.h>  
#include<unistd.h>  
#include<stdlib.h>  
void when_alarm();  
void when_sigint();  
void when_sigchld(int);  
void when_sigusr1();  
void when_sigio();  
int main()  
{  int childpid;//子程序进程ID号  printf("程序已经开始运行,5秒钟后将接收到时钟信号。/n");  if ((childpid=fork())>0)//父进程  {  signal(SIGALRM,when_alarm);  //当接收到SIGALRM信号时,调用when_alarm函数  signal(SIGINT,when_sigint);  //当接收到SIGINT信号时,调用when_sigint函数  signal(SIGCHLD,when_sigchld);//当接收到SIGCHLD信号时,调用when_sigchld函数  signal(SIGUSR1,when_sigusr1);//当接收到SIGUSR1信号时,调用when_sigusr1函数  signal(SIGIO,when_sigio);//当接收到SIGIO信号时,调用when_sigio函数  alarm(5);     //5秒钟之后产生SIGALRM信号  raise(SIGIO); //向自己发送一个SIGIO信号  pause(); //将父进程暂停下来,等待SIGALRM信号到来  pause(); //将父进程暂停下来,等待SIGUSR1信号到来  pause(); //将父进程暂停下来,等待SIGCHLD信号到来  printf("------此时程序会停下来等待,请按下ctrl+c送出SIGINT信号-------/n");  pause(); //将父进程暂停下来,等待SIGINT信号到来          }  else if(childpid==0) //子进程  {  int timer;  for(timer=7;timer>=0;timer--) //时钟计时5秒产生SIGALRM信号,再过2秒子进程退出,产生SIGCHLD信号  {  if(timer>2)      printf("距离SIGALRM信号到来还有%d秒。/n",timer-2);  if(timer==4)  kill(getppid(),SIGUSR1); //向父进程发送一个SIGUSR1信号  if((timer<=2)&&(timer>0))  printf("子进程还剩%d秒退出,届时会产生SIGCHLD信号。/n",timer);  if(timer==0) //子进程退出,产生SIGCHLD信号  raise(SIGKILL); //子进程给自己发一个结束信号  sleep(1); //每个循环延时1秒钟  }          }  else  printf("fork()函数调用出现错误!/n");  return 0;  
}  
void when_alarm()  
{  printf("5秒钟时间已到,系统接收到了SIGALRM信号!/n");  
}  
void when_sigint()  
{  printf("已经接收到了SIGINT信号,程序将退出!/n");  exit(0);  
}  
void when_sigchld(int SIGCHLD_num)  
{  printf("收到SIGCHLD信号,表明我的子进程已经中止,SIGCHLD信号的数值是:%d。/n",SIGCHLD_num);  
}  
void when_sigusr1()  
{  printf("系统接收到了用户自定义信号SIGUSR1。/n");  
}  
void when_sigio()  
{  printf("系统接收到了SIGIO信号。/n");  
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/292050.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

技术分享 | 微服务模式下如何高效进行API测试

导读&#xff1a;微服务架构下&#xff0c;API 测试的最大挑战来自于庞大的测试用例数量&#xff0c;以及微服务之间的相互耦合。基于这种挑战&#xff0c;如何进行高效的API测试&#xff0c;选择什么样的方式就比较重要&#xff0c;此文主要是采用契约测试的方法来对微服务模式…

由CloudStack项目引起的ESXI嵌套虚拟化引起的二级虚拟机无法被访问

关于这个问题&#xff0c;主要以文字描述为主&#xff0c;最终解决方法其实就一个步骤。问题描述&#xff1a;某客户需要部署某企业的云平台&#xff0c;但是由于年前没有足够的物理机资源&#xff0c;所以提供的资源均为虚拟机&#xff0c;现在让我们做技术评估。其实观察整个…

美女的床真的好难爬......

1 地中海式茂密&#xff1f;▼2 阴着呐▼3 拜拜了您呐▼4 草莓从哪里来▼5 爷青结系列▼6 没点才艺还住不了酒店了▼7 美女的床果真很难爬(真从500平大床中醒来)▼8 数学能有多有趣▼你点的每个赞&#xff0c;我都认真当成了喜欢

控制器方法错误处理

错误处理一直是开发维护阶段需要重点关注的一块&#xff0c;控制器中方法原则上都需要处理错误。 1、添加BaseController 路径&#xff1a;nweb\src\main\java\com\nankang\cati\nweb\controller\BaseController.java 所有的控制器都继承BaseController 2、使用&#xff1a; 1&…

EF Core 6 新功能汇总(一)

在这篇文章中&#xff0c;你将看到 EF Core 6 中的十个新功能&#xff0c;包括新的特性标注&#xff0c;对时态表、稀疏列的支持&#xff0c;以及其他新功能。1Unicode 特性在 EF Core 6.0 中&#xff0c;新的 UnicodeAttribute 允许你将一个字符串属性映射到一个非 Unicode 列…

DS5020配置集群存储

一、方案设计 计划给某公司服务器制作集群&#xff0c;存储划分大致如下&#xff1a; 1、 将存储磁盘制作为raid5&#xff1b; 2、 划分两个Storage Partition给两类集群使用&#xff0c;一类为数据库服务&#xff0c;一类为各种应用服务 二、存储的连接 1、存储的简介 Serial …

RequireJS首次加载偶尔失败

现象&#xff1a;第一次加载JS文件&#xff0c;首次加载偶尔失败&#xff1b; 原因&#xff1a;require([jquery, operamasks, zTree, jQueryCookie]&#xff0c;中前后引用同步加载&#xff1b; 解决方式&#xff1a;shim声明前置加载&#xff1b; 配置如下&#xff1a; requi…

linux之file命令总结

解释&#xff1a; file是通过查看文件的头部内容&#xff0c;来获取文件的类型使用file命令可以知道某个文件究竟是二进制&#xff08;ELF格式&#xff09;的可执行文件, 还是Shell Script文件&#xff0c;或者是其它的什么格式。 file能识别的文件类型&#xff1a;目录、Shel…

优化.NET 应用程序 CPU 和内存的11 个实践

https://michaelscodingspot.com/cpu-bound-memory-bound/优化.NET 应用程序 CPU 和内存的11 个实践凡事都有其限度&#xff0c;对吧&#xff1f;汽车只能开这么快&#xff0c;进程只能使用这么多内存&#xff0c;程序员只能喝这么多咖啡。我们的生产力受到资源的限制&#xff…

陈省身:三角形内角和不等于180°

全世界只有3.14 % 的人关注了爆炸吧知识三角形外角和为360作为公认的劳模&#xff0c;平日里&#xff0c;超模君不但要码字&#xff0c;工作之余还要监督表妹做作业&#xff0c;也难怪表妹成绩总是能名列前茅。今天表妹做作业时&#xff0c;遇到一道判断题&#xff1a;“三角形…

跟我学PHP第二篇- 配置Mysql以及PHP WampServer篇(1)

大家好&#xff0c;昨天我给大家介绍了如何去安装ZEND STUDIO&#xff0c;下面昨天文章的链接&#xff1a; http://www.cnblogs.com/kmsfan/p/zendStudio.html 本节为配置的第一部分&#xff0c;还没有讲完全部&#xff0c;因为个人工作比较忙&#xff0c;没有一整天时间写博客…

linux之查看文件大小和磁盘大小总结

1 、查看文件大小 使用du命令,查看该目录以及子目录文件的大小 du -h 如果只需要快速查看这个目录占用大小&#xff0c;可用下面命令 du -sh 比如我们查看xiaoyun这个文件大小 2、查看电脑磁盘大小 使用下面命令 df -h 效果如下图 很明显系统装载/dev/sda2下

YARP(Yet Another Reverse Proxy)是使用 .NET 构建的高度可定制的反向代理

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;16分钟)YARP 1.0已经发布了&#xff0c;现在可以从 NuGet 下载。YARP&#xff08;Yet Another Reverse Proxy&#xff09;是使用 .NET 构建的高度可定制的反向代理。YARP 与其他反向代理的最大区别在于它是如何构建和…

电影院里为何有散落的青瓜?

1 摄像头&#xff1a;你套个袋子我就认不出来了吗&#xff1f;▼2 路边惊现大熊猫&#xff01;&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼3 好一个驼小姐&#xff08;via.豆瓣社死小组满杯草莓&#xff09;▼4 学弟的理解也不是无迹可寻▼5 台湾人过生日的方…

java中List、Map、Set、Collection、Stack、Queue等的使用

java中这几个东西是比较常用的&#xff0c;虽然我用的不多&#xff0c;也正是因为用的不多&#xff0c;所以我一直搞不清楚他们之间的具体用法以及相互之间的关系&#xff0c;现在特单独作为一个东西来总结一下。 本文参考一下资料&#xff1a; 1.《java编程思想》一书第11章 2…

开发文档模板_需求文档模板一堆什么样的适合你呢?

产品经理的日常中用的最多的是产品需求文档&#xff0c;这个文档应该可以说是产品经理将需求落到是明面上的一步。我们的文档需要给相关的人员进行共同的看&#xff0c;不然文档就没有存在的意义了&#xff0c;文档不只是简单的线框图和一些自己也看不明白的词汇。实际中很少开…

Briefly unavailable for scheduled maintenance message after doing automatic upgrade

为什么80%的码农都做不了架构师&#xff1f;>>> 今天突然不能打开wordpress&#xff0c;报了“Briefly unavailable for scheduled maintenance message after doing automatic upgrade” 这个错误&#xff0c;一下懵逼了。 Google之后&#xff0c;发现是wordpress…

搞IT的技术人员为什么会如此苦逼

http://www.cnblogs.com/springmvc-hibernate/archive/2012/05/10/2493733.html —————————————————————————————————————————————————————— 为什么苦逼&#xff1f; 原因一大堆&#xff0c;对于外部的因数&#xff0c;我…

为什么越来越多的开发者选择使用Spring Boot

Web应用开发背景 使用Java做Web应用开发已经有近20年的历史了&#xff0c;从最初的Servlet1.0一步步演化到现在如此多的框架&#xff0c;库以及整个生态系统。经过这么长时间的发展&#xff0c;Java作为一个成熟的语言&#xff0c;也演化出了非常成熟的生态系统&#xff0c;这…