• 中断及信号


      0、部分参考自http://lexandros.blog.163.com/blog/static/1855665882012830058151/

      1、(1)中断:计算机在执行程序的过程中,当出现异常情况或特殊请求时,中断系统将迫使CPU暂停正在执行的程序,转而去进行中断事件的处理,中断处理完毕后,再返回被中断程序的间断处,继续执行原程序。

      硬件中断导致CPU通过一个上下文切换来保存执行状态(如程序计数器和程序状态字等寄存器信息);软件中断则通常作为CPU指令集中的一个指令,以可编程的方式直接指示这种上下文切换,并将处理导向一段中断处理代码。

      (2)中断的作用:中断在计算机多任务处理,尤其是实时系统中尤为有用。

      若没有中断,CPU与外部设备通信时必须在向该设备发出指令后进行忙等待,反复轮询该设备是否完成了动作并返回结果,造成大量CPU周期的浪费。引入中断后,在CPU发出设备请求后可以立即返回以处理其它任务,当设备完成动作时才发送中断信号给CPU,后者再对结果进行处理。

      (3)中断的类型:从是否可被屏蔽来看,可分为不可屏蔽中断(NMI。如软件中断、电源掉电、总线出错、时钟中断)和可屏蔽中断(除受本身屏蔽位控制外,还受CPU标志寄存器中的中断允许标志位IF控制。IF位可以由用户控制。如系统启动执行初始化程序时屏蔽键盘中断,使初始化程序得以顺利进行)。

      中断源:外部设备(如键盘、打印机完成自身操作后向CPU发出中断请求);故障强迫中断(如运算溢出、电源掉电);实时时钟请求中断(到达规定时间,时钟电路发出中断请求);数据通道中断(也称DMA操作中断,如磁盘直接与存储器交换数据所要求的中断);程序自愿中断(如CPU执行了自陷指令——软中断指令,引发特殊异常,从而进入内核态)。 

      中断向量表:中断向量即中断源的识别标志,可用来存放中断服务程序的入口地址或跳转到中断服务程序的入口地址。在PC/AT中,规定内存储器的最低1KB用来存放中断向量(共256个),称这一片内存区为中断向量表。

      中断嵌套:指中断系统放弃当前正在执行的中断服务程序时,转而去响应另一个优先级更高的中断请求,处理完毕后再返回到原先被中断的中断服务程序。

      中断的开启和关闭:关中断是为了保护一些不能中途停止执行的程序而设计的,如恢复现场时CPU不允许被打断,此时就要暂时关闭中断。


      2、信号是一种软件中断,提供一种处理异步事件的方法。

      1)信号的产生条件:某些按键如Ctrl-C;硬件异常(除0、内存越界等);kill命令(默认发送SIGTERM信号);某种软件条件已发生并应将其通知给有关进程时(如SIGALRM)。

      信号的几种处理方式:忽略(若忽略由硬件异常产生的信号,进程的运行行为是未定义的);捕捉(通知内核在信号发生时调用信号处理函数来执行用户对这种事件的处理);默认(一般是终止进程)。

      man 7 signal:描述了信号的产生条件和默认处理方式等。Term表示终止进程、Ign表示忽略信号、Core表示终止进程并coredump、Stop表示停止进程(如kill -SIGSTOP,相当于Ctrl-Z)、Cont表示继续运行处于停止状态的进程(kill -SIGCONT。作业由Stopped状态变成Running状态)。如在最初的POSIX.1-1990标准中SIGINT、SIGKILL和SIGALRM的默认处理方式是Term,而SIGQUIT(Ctrl-)和SIGSEGV是Core。

      另外,SIGKILL和SIGSTOP信号不能被捕捉、阻塞或忽略。SIGKILL和SIGTERM都可用于终止进程,不同的是进程能够捕捉、阻塞或忽略SIGTERM

      实时信号:在linux中,实时信号的范围从SIGRTMIN到SIGRTMAX(一般使用SIGRTMIN + 1、SIGRTMIN + 2...表示)。由于没有预定义,程序使用这些信号时可自行定义,但是需要注意LinuxThreads的实现已经使用了前三个实时信号。若进程收到实时信号而未处理,默认会被终止。

      2)signal函数:void (*signal(int sig, void (*func)(int)))(int);

      用typedef表达可使signal的原型变得更简单:typedef void sig_func(int); sig_func *signal(int, sig_func *);

      参数1指明要处理的信号(如SIGINT),参数2描述了如何处理该信号,其值或为一个信号处理函数的地址,或为常量SIG_IGN,或为常量SIG_DFL。

      成功则返回信号原来的处理函数的指针,出错则返回SIG_ERR并设置errno。

      示例:

    #include <stdio.h>
    #include <signal.h>
    #include <sys/wait.h>
    #include <unistd.h>
    #include <stdlib.h> #include <string.h> #define MAXLINE 65535 // 信号处理函数 void sig_int(int signo) { printf("interrupt %%"); } int main(void) { char buf[MAXLINE]; if (signal(SIGINT, sig_int) == SIG_ERR) { printf("signal error"); } printf("%%"); while (fgets(buf, MAXLINE, stdin) != NULL) { if(buf[strlen(buf)-1] == ' ') { buf[strlen(buf) - 1] = 0; } pid_t pid; if((pid = fork()) < 0) { printf("fork error"); } // 子进程处理命令行中输入的命令 else if (pid == 0) { execlp(buf, buf, (char *)0); printf("couldn't execute:%s",buf); exit(127); } // 父进程等待子进程停止或终止 int status = 0; if((pid = waitpid(pid, &status, 0)) < 0) { printf("waitpid error"); } printf("%%"); } exit(0); }

      signal函数唯一可移植性的使用方式是设置信号的SIG_DFL和SIG_IGN动作,而使用它建立信号处理函数在不同系统间有不同的语义。建议使用sigaction代替之。

    不断学习中。。。

  • 相关阅读:
    POJ 最小球覆盖 模拟退火
    POJ 1379 模拟退火
    PythonTip(2)
    PythonTip(1)
    LA 3353 最优巴士线路设计
    LA 4254 贪心
    判断分析
    因子分析——因子得分
    因子分析——应用
    因子分析——因子旋转
  • 原文地址:https://www.cnblogs.com/hanerfan/p/3592826.html
Copyright © 2020-2023  润新知