您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 销售管理 > 02_linux信号专题讲座-v1.0.1-王保明
轻松入门实战应用从项目开发角度为你搭建完整的知识体系wangbaominglinux信号-应用编程-专题讲座writtenby王保明linux信号基本概念1基本概念中断中断是系统对于异步事件的响应中断信号中断源现场信息中断处理程序中断向量表异步事件的响应:进程执行代码的过程中可以随时被打断,然后去执行异常处理程序生活中的中断和计算机系统中的中断1)无中断生活场景张三看书,厨房烧水2)有中断的生活场景张三看书,设置闹钟,厨房烧水。闹钟发出中断信号,张三把书合好(第20页),去厨房把开水事情处理好,张三重新打开20页进行阅读。3)计算机系统的中断场景中断源发出中断信号,CPU判断中断是否屏蔽屏蔽、保护现场,cpu执行中断处理程序,cpu恢复现场,继续原来的任务。4)中断的其他概念中断向量表保存了中断处理程序的入口地址。中断个数固定,操作系统启动时初始化中断向量表。中断有优先级(有人敲门,有人打电话,有优先级)中断可以屏蔽(张三可以屏蔽电话)。中断分类硬件中断(外部中断)外部中断是指由外部设备通过硬件请求的方式产生的中断,也称为硬件中断软件中断(内部中断)内部中断是由CPU运行程序错误或执行内部程序调用引起的一种中断,也称为软件中断。x86平台INT指令ARM软中断指令SWI信号概念信号是UNIX系统响应某些状况而产生的事件,进程在接收到信号时会采取相应的行轻松入门实战应用从项目开发角度为你搭建完整的知识体系wangbaoming动。信号是因为某些错误条件而产生的,比如内存段冲突、浮点处理器错误或者非法指令等信号是在软件层次上对中断的一种模拟,所以通常把它称为是软中断信号和中断的区别信号与中断的相似点:(1)采用了相同的异步通信方式;(2)当检测出有信号或中断请求时,都暂停正在执行的程序而转去执行相应的处理程序;(3)都在处理完毕后返回到原来的断点;(4)对信号或中断都可进行屏蔽。信号与中断的区别:(1)中断有优先级,而信号没有优先级,所有的信号都是平等的;(2)信号处理程序是在用户态下运行的,而中断处理程序是在核心态下运行;(3)中断响应是及时的,而信号响应通常都有较大的时间延迟。2信号名称及常用信号信号名称描述SIGABRT进程停止运行6SIGALRM警告钟SIGFPE算述运算例外SIGHUP系统挂断SIGILL非法指令SIGINT终端中断2SIGKILL停止进程(此信号不能被忽略或捕获)SIGPIPE向没有读者的管道写入数据SIGSEGV无效内存段访问SIGQUIT终端退出3SIGTERM终止SIGUSR1用户定义信号1SIGUSR2用户定义信号2SIGCHLD子进程已经停止或退出SIGCONT如果被停止则继续执行SIGSTOP停止执行SIGTSTP终端停止信号SIGTOUT后台进程请求进行写操作SIGTTIN后台进程请求进行读操作轻松入门实战应用从项目开发角度为你搭建完整的知识体系wangbaoming实验1:kill–l可以查看linux内核支持的信号Man7signal查看信号的默认动作、信号的含义3信号处理进程对信号的三种相应忽略信号不采取任何操作、有两个信号不能被忽略:SIGKILL(9号信号)和SIGSTOP。思考1:为什么进程不能忽略SIGKILL、SIGSTOP信号。(如果应用程序可以忽略这2个信号,系统管理无法杀死、暂停进程,无法对系统进行管理。)。SIGKILL(9号信号)和SIGSTOP信号是不能被捕获的。捕获并处理信号内核中断正在执行的代码,转去执行先前注册过的处理程序。执行默认操作默认操作通常是终止进程,这取决于被发送的信号。信号的默认操作:通过man7signal进程查看man7signal编程实践:让应用程序捕捉ctrl+c信号以ctrl+c会产生一个中断。当前应用程序捕捉ctrl+c中断信号。4信号signal函数编程实践signal信号安装函数signal函数,作用1:站在应用程序的角度,注册一个信号处理函数。作用2:忽略信号、设置信号默认处理信号的安装和恢复typedefvoid(*__sighandler_t)(int);轻松入门实战应用从项目开发角度为你搭建完整的知识体系wangbaoming#defineSIG_ERR((__sighandler_t)-1)#defineSIG_DFL((__sighandler_t)0)#defineSIG_IGN((__sighandler_t)1)函数原型:__sighandler_tsignal(intsignum,__sighandler_thandler);参数signal是一个带signum和handler两个参数的函数,准备捕捉或屏蔽的信号由参数signum给出,接收到指定信号时将要调用的函数由handler给出handler这个函数必须有一个int类型的参数(即接收到的信号代码),它本身的类型是voidhandler也可以是下面两个特殊值:SIG_IGN屏蔽该信号SIG_DFL恢复默认行为编程实践注册SIGINT、注册SIGQUIT编程实践:信号的安装和恢复//测试信号的安装与恢复intmain(void){__sighandler_toldHandle;//sighandler_t*oldHandle;printf(main....begin\n);oldHandle=signal(SIGINT,myhandle);if(oldHandle==SIG_ERR){perror(funcsignalerr\n);return0;}printf(ifuentera,resetsignal\n);while(getchar()!='a'){;}//键入a以后,恢复默认函数/*if(signal(SIGINT,oldHandle)==SIG_ERR){perror(funcsignalerr\n);return0;}*/轻松入门实战应用从项目开发角度为你搭建完整的知识体系wangbaomingif(signal(SIGINT,SIG_DFL)==SIG_ERR){perror(funcsignalerr\n);return0;}while(1);return0;}注意:signal函数函数返回值RETURNVALUEThesignal()functionreturnsthepreviousvalueofthesignalhandler,orSIG_ERRonerror.5可靠信号、不可靠信号不可靠信号PK可靠信号linux信号机制基本上是从unix系统中继承过来的。早期unix系统中的信号机制比较简单和原始,后来在实践中暴露出一些问题,它的主要问题是:进程每次处理信号后,就将对信号的响应设置为默认动作。在某些情况下,将导致对信号的错误处理;因此,用户如果不希望这样的操作,那么就要在信号处理函数结尾再一次调用signal(),重新安装该信号。早期unix下的不可靠信号主要指的是进程可能对信号做出错误的反应以及信号可能丢失。linux支持不可靠信号,但是对不可靠信号机制做了改进:在调用完信号处理函数后,不必重新调用该信号的安装函数(信号安装函数是在可靠机制上的实现)。因此,linux下的不可靠信号问题主要指的是信号可能丢失。总结:unix信号机制不可靠地方,1)处理完信号以后,需要重新再注册信号;2)信号可能丢失。linux下已经对1做了优化。可靠信号随着时间的发展,实践证明,有必要对信号的原始机制加以改进和扩充。所以,后来出现的各种unix版本分别在这方面进行了研究,力图实现可靠信号。由于原来定义的信号已有许多应用,不好再做改动,最终只好又新增加了一些信号,并在一开始就把它们定义为可靠信号,这些信号支持排队,不会丢失。同时,信号的发送和安装也出现了新版本:信号发送函数sigqueue()及信号安装函数sigaction()。总结:sigaction和signal函数,都是调用内核服务do_signal函数;内核服务函数(应用系统无法调用的函数)实时信号(都是可靠信号)和非实时信号(不可靠信号)早期Unix系统只定义了32种信号,Rethat7.2支持64种信号,编号0-63(SIGRTMIN=31,SIGRTMAX=63),将来可能进一步增加,这需要得到内核的支持。轻松入门实战应用从项目开发角度为你搭建完整的知识体系wangbaoming前32种信号已经有了预定义值,每个信号有了确定的用途及含义,并且每种信号都有各自的缺省动作。如按键盘的CTRL+C时,会产生SIGINT信号,对该信号的默认反应就是进程终止。后32个信号表示实时信号,等同于前面阐述的可靠信号。这保证了发送的多个实时信号都被接收。实时信号是POSIX标准的一部分,可用于应用进程。非实时信号都不支持排队,都是不可靠信号;实时信号都支持排队,都是可靠信号。实时信号和非实时信号Man7signal查看手册非实时信号都不支持排队,都是不可靠信号;实时信号都支持排队,都是可靠信号6信号发送kill函数Kill基本用法发送信号的函数有kill和raise区别:kill既可以向自身发送信号,也可以向其他进程发送信号;raise函数向进程自身发送信号。Intkill(pid_tpid,intsiq)intraise(intsigno)Intkill(pid_tpid,intsiq)参数组合情况解释:kill(pid_tpid,intsiq)pid0将信号sig发给pid进程pid=0将信号sig发给同组进程pid=-1将信号sig发送给所有进程,调用者进程有权限发送的每一个进程(除了1号进程之外,还有它自身)pid-1将信号sig发送给进程组是pid(绝对值)的每一个进程实验://子进程向父进程发送信号//子进程向同组进程发送信号(getpgrp()函数获取进程组pid)结论:注意,如果在fork之前安装信号,则子进程可以继承信号。kill和sleep在一起子进程向父进程发送信号sleep函数几点说明1)sleep函数作用,让进程睡眠。2)能被信号打断,然后处理信号函数以后,就不再睡眠了。直接向下执行代码3)sleep函数的返回值,是剩余的秒数轻松入门实战应用从项目开发角度为你搭建完整的知识体系wangbaomingraise函数raiseraise给自己发送信号。raise(sig)等价于kill(getpid(),sig);killpg给进程组发送信号。killpg(pgrp,sig)等价于kill(-pgrp,sig);sigqueue给进程发送信号,支持排队,可以附带额外数据信息。pause函数pause()函数将进程置为可中断睡眠状态。然后它调用内核函数schedule(),使linux进程调度器找到另一个进程来运行。pause使调用者进程挂起,直到一个信号被捕获alarm函数alarm函数,设置一个闹钟延迟发送信号告诉linux内核n秒中以后,发送SIGALRM信号;;手册描述:NAMEalarm-setanalarmclockfordeliveryofasignalSYNOPSIS#includeunistd.hunsignedintalarm(unsignedintseconds);DESCRIPTIONalarm()arrangesforaSIGALRMsignaltobedeliveredtotheprocessinsecondsseconds.Ifsecondsiszero,nonewalarm()isscheduled.Inanyeventanypreviouslysetalarm()iscancelled.实验1:手工发送信号alarm信号实践kill-ALRM21333kill-14213333kill-SIGALRM213333命令发送信号实践kill-alram`ps-aux|grep01aram|grep-vvi|awk'{print$2}'
本文标题:02_linux信号专题讲座-v1.0.1-王保明
链接地址:https://www.777doc.com/doc-3117255 .html