中断

中断是系统对于异步事件的响应, 进程执行代码的过程中可以随时被打断,然后去执行异常处理程序;

计算机系统的中断场景:中断源发出中断信号 -> CPU判断中断是否屏蔽屏蔽以及保护现场 -> CPU(查询中断向量表, 找到中断服务程序的入口地址)执行中断处理程序 ->(处理完中断之后) ->恢复现场,继续执行原来的任务

中断分类

硬件中断(外部中断)

外部中断是指由外部设备通过硬件请求的方式产生的中断,也称为硬件中断

软件中断(内部中断)

内部中断是由CPU运行程序错误或执行内部程序调用引起的一种中断,也称为软件中断(如:执行除0操作, 由用户空间陷入内核空间等)。

信号

信号是UNIX/Linux系统响应某些状况而产生的事件,进程在接收到信号时会采取相应的行动。信号一般是因为某些错误条件而产生的,比如内存段冲突、浮点处理器错误或者非法指令等;信号是在软件层次上对中断的一种模拟,所以通常把它称为是软中断;

信号与中断的相似点:

(1)采用了相同的异步通信方式;

(2)当检测出有信号或中断请求时,都暂停正在执行的程序而转去执行相应的处理程序;

(3)都在处理完毕后返回到原来的断点;

(4)对信号或中断都可进行屏蔽。

信号与中断的区别:

(1)中断有优先级,而信号没有优先级,所有的信号都是平等的;

(2)信号处理程序是在用户态下运行的,而中断处理程序是在核心态下运行;

(3)中断响应是及时的,而信号响应通常都有较大的时间延迟。

常用信号

信号名称

描述

SIGABRT(6)

进程停止运行

SIGALRM

警告钟

SIGFPE

算述运算例外(如除0)

SIGHUP

系统挂断

SIGILL

非法指令

SIGINT(2)

终端中断

SIGKILL

停止进程(此信号不能被忽略或捕获)

SIGPIPE

向没有读者的管道写入数据

SIGSEGV

无效内存段访问

SIGQUIT

终端退出

SIGTERM

终止

SIGUSR1

用户定义信号1

SIGUSR2

用户定义信号2

SIGCHLD

子进程已经停止或退出

SIGCONT

如果被停止则继续执行

SIGSTOP

停止执行

SIGTSTP

终端停止信号

SIGTOUT

后台进程请求进行写操作

SIGTTIN

后台进程请求进行读操作

进程对信号的响应 

忽略信号

不采取任何操作、有两个信号不能被忽略:SIGKILL和SIGSTOP。

[为什么进程不能忽略SIGKILL/SIGSTOP信号。(如果应用程序可以忽略这2个信号,系统管理无法杀死、暂停进程,无法对系统进行管理。)]

捕获并处理信号

内核中断正在执行的代码,转去执行先前注册过的处理程序。

执行默认操作

默认操作通常是终止进程,这取决于被发送的信号。

信号的默认操作:通过 man 7 signal 查看

信号安装-signal

typedef void (*__sighandler_t) (int);
#define SIG_ERR ((__sighandler_t) -1)
#define SIG_DFL ((__sighandler_t) 0)
#define SIG_IGN ((__sighandler_t) 1)
__sighandler_t signal(int signum, __sighandler_t handler);

参数

signal是一个带signum和handler两个参数的函数,准备捕捉或屏蔽的信号由参数signum给出,接收到指定信号时将要调用的函数由handler给出

handler这个函数必须有一个int类型的参数(即接收到的信号代码),它本身的类型是void, handler也可以是下面两个特殊值:

SIG_IGN 屏蔽该信号

SIG_DFL 恢复默认行为

//示例1
void handler(int sigNum)
{
    cout << "recv a signal = " << sigNum << endl;
}

int main(int argc, char *argv[])
{
    signal(SIGINT, handler);
    while (true)
        sleep(1);
}

RETURN VALUE

signal() returns the previous value of the signal handler, or SIG_ERR on error.

In  the event of an error, errno is set to indicate the cause.

int main(int argc, char *argv[])
{
    sighandler_t oldHandler = signal(SIGINT, handler);
    if (oldHandler == SIG_ERR)
        err_exit("signal error");

    while (getchar() != '\n')
        sleep(1);

    // 等价于 signal(SIGINT, SIG_DFL)
    if (signal(SIGINT, oldHandler) == SIG_ERR)
        err_exit("signal error");

    while (true)
        sleep(1);
}
//实例: 捕获所有信号, 并打印信号的信息
int main()
{
    for (int i = 1; i < NSIG; ++i)
    {
        if (signal(i, sigHandler) == SIG_ERR)
        {
            cerr << "signal " << i << ": " << strsignal(i) << " set error";
            cerr << ", errno desc: " << strerror(errno) << endl;
        }
    }

    while (true)
        pause();
}

void sigHandler(int signo)
{
    cout << "catch a signal, signo = " << signo << ", desc: " << strsignal(signo) << endl;
}

Linux信号实践(1) --Linux信号编程概述的更多相关文章

  1. Linux信号实践(4) --可靠信号

    Sigaction #include <signal.h> int sigaction(int signum, const struct sigaction *act, struct si ...

  2. Linux进程实践(1) --Linux进程编程概述

    进程 VS. 程序 什么是程序? 程序是完成特定任务的一系列指令集合. 什么是进程? [1]从用户的角度来看:进程是程序的一次执行过程 [2]从操作系统的核心来看:进程是操作系统分配的内存.CPU时间 ...

  3. Linux信号实践(2) --信号分类

    信号分类 不可靠信号 Linux信号机制基本上是从UNIX系统中继承过来的.早期UNIX系统中的信号机制比较简单和原始,后来在实践中暴露出一些问题,它的主要问题是: 1.进程每次处理信号后,就将对信号 ...

  4. Linux驱动实践:中断处理函数如何【发送信号】给应用层?

    作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...

  5. Linux信号实践(3) --信号内核表示

    信号在内核中的表示 执行信号的处理动作称为信号递达(Delivery),信号从产生到递达之间的状态,称为信号未决(Pending).进程可以选择阻塞(Block)某个信号.被阻塞的信号产生时将保持在未 ...

  6. 与信号相关的linux系统编程API

    1. kill(pid_t pid, int sig); //给指定的进程发送sig信号   raise(int sig); //给当前进程发送sig信号2. 处理指定的信号    typedef v ...

  7. linux 进程学习笔记-进程信号sigal

    信号(或软中断)是在软件层次上对中断的一个模拟,其运行在“用户空间”,一个进程对另外一个或几个进程通过发送信号来实现异步通信.当接收进程接收到信号后,其可以注册一下处理函数来说对这些信号进行处理(也可 ...

  8. xenomai内核解析之信号signal(一)---Linux信号机制

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有错误,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 目录 1. Linux信号 1.1注册信号处理函数 ...

  9. Linux下shell脚本中信号捕获和函数练习脚本之ping一个网段

    该脚本主要的目的是练习在Linux bash脚本中捕获信号,顺便练习一下函数的使用,还有就是终止一个正在运行的程序后,该程序打开的文件的后续处理问题等等!脚本功能:  ping一个网段内的IP,检测哪 ...

随机推荐

  1. 561. Array Partition I

    Given an array of 2n integers, your task is to group these integers into n pairs of integer, say \(( ...

  2. map函数、filer函数、reduce函数的用法和区别

    Map函数 map函数的用法如下: def add_one(x): return x+1 #使用普通函数 v1 = map(add_one,[1,2,3]) v1 = list(v1) print(v ...

  3. Linux服务器搭建相关教程链接整理

    Linux: Linux 教程 | 菜鸟教程 linux下如何添加一个用户并且让用户获得root权限 - !canfly - 博客园 Git: 在 Linux 下搭建 Git 服务器 - 黄棣-dee ...

  4. Vue结合slot插槽分发父组件内容实现高度复用、更加灵活的dialog组件

    之前写过一篇关于vue实现dialog会话框组件的文章(http://www.cnblogs.com/fozero/p/8546883.html)[http://www.cnblogs.com/foz ...

  5. Scala:函数和闭包

    http://blog.csdn.net/pipisorry/article/details/52902271 Scala函数 Scala 有函数和方法,二者在语义上的区别很小.Scala 方法是类的 ...

  6. 基于Web在线考试系统的设计与实现

    这是一个课程设计的文档,源码及文档数据库我都修改过了,貌似这里复制过来的时候图片不能贴出,下载地址:http://download.csdn.net/detail/sdksdk0/9361973   ...

  7. 在Windows Service 2012上安装IIS 8.0 IIS 6

    我的目的是在服务器上安装IIS6 ,但是受到这边文章的启发和按照他的步骤,看到了"IIS 6管理兼容性",我的问题就决解了,我这里是因为要安装vss 2005 和u8等比较早期的软 ...

  8. windows系统下安装和使用ROS的解决方案 (1 win_ros 2 rosserial_windows)

    具体请参考官网: 1  http://wiki.ros.org/win_ros 2  https://github.com/ros-windows/win_ros 3  http://wiki.ros ...

  9. React Native开发工具Nuclide使用

    之前写RN的时候首选webstorm,这是之前做前端已经习惯的工具,其实RN开发官网推荐的是Nuclide工具, Nuclide是Fackbook专门为React开发IDE,今天也来尝试下,如果对we ...

  10. Linux Debugging(八): core真的那么难以追踪吗?

    本周遇到了好几个core都很有典型性.在这里和大家分享下. 相信有过Linux编程经验的人,肯定都遇到过.感觉周围人很多对core有天然的恐惧感,尤其对刚入行不久的同学来说.当然了,也有工作好几年看到 ...