细说Linux中的信号(signal )

在细说信号之前我们先来了解下什么是信号。信号(signal)是一种软件中断,它提供了一种处理异步事件的方法,也是进程间惟一的异步通信方式。在Linux系统中,根据POSIX标准扩展以后的信号机制,不仅可以用来通知某种程序发生了什么事件,还可以给进程传递数据。

信号的种类有很多,我们可以通过kill -l命令察看系统定义的信号列表:

可以看到一共有62个信号。1-31号为普通信号;34-64号为实时信号。(博主这次只讨论普通信号。)

接下来我们来细说信号的产生、阻塞和捕捉。

>>信号的产生:

  1. 通过终端按键产生信号 ;

    通过下面的代码写一个死循环:

    可以通过键盘输入Ctrl+\进行终止该进程:

  2. 调用系统函数向进程发信号;

    在后台执行死循环程序,然后用kill命令给它发SIGSEGV信号:(按两次回车)

  3. 用软件条件产生信号;

    调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发 SIGALRM信号, 该信号的默认处理动作是终止当前进程。这个函数的返回值是0或者是以前设定的闹钟时间还余下的秒数。

    该程序是用在1秒钟内不停的计数,直到1秒中到了被SIGALRM信号终止掉进程。

>>阻塞信号

  1. 信号在内核中的表示:

    实际执行信号的处理动作称为信号递达(Delivery),信号从产生到递达之间的状态,称为信号未决(Pending)。进程可以选择阻塞 (Block )某个信号。被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞, 才执行递达的动作。

    Notice:阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。

    信号在内核中的表示示意图:

    每个信号都有两个标志位来表示阻塞和未决和一个函数指针来表示处理动作。

  2. 信号集操作函数:

    sigset_t类型对于每种信号用一个bit表示“有效”或“无效”状态,至于这个类型内部如何存储这 些bit则依赖于系统实现不是我们所关心的问题。

    我们可以通过调用以下函数来进行操作sigset_t变量

    int sigemptyset(sigset_t *set);//初始化set所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号

    int sigfillset(sigset_t *set);//初始化set所指向的信号集,使其中所有信号的对应bit置位,表示该信号集的有效信号包括系统支持的所有信号

    int sigaddset(sigset_t *set, int signo);//在该信号集中添加或删除某种有效信号

    int sigdelset(sigset_t *set, int signo);//在该信号集中添加 或删除某种有效信号

    int sigismember(const sigset_t *set, int signo); //是一个布尔函数,用于判断一个信号集的有效信号中是否包含某种信号,若包含则返回1,不包含则返回0, 出错返回-1

  3. sigprocmask 函数和sigpending 函数

    int sigprocmask(int how, const sigset_t *set, sigset_t *oset);

    调用函数sigprocmask可以读取或更改进程的信号屏蔽字(阻塞信号集)。若成功则为0,若出错则为-1。

    int sigpending(sigset_t *set);

    sigpending读取当前进程的未决信号集,通过set参数传出。调用成功则返回0,出错则返回 -1。

    结果如下:

    上述程序利用printsigset()函数将指定信号集的所有信号的存在情况打印出来。

    sigprocmask 执行完毕后,SIGINT信号就相当于被阻塞了。

时间: 2024-12-15 02:03:22

细说Linux中的信号(signal )的相关文章

浅谈Linux中的信号机制(二)

首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Linux内核源码评头论足.以后的路还很长,我还是一步一个脚印的慢慢走着吧,Linux内核这座山,我才刚刚抵达山脚下. 好了,言归正传,我接着昨天写下去.如有错误还请各位看官指正,先此谢过. 上篇末尾,我们看到了这样的现象:send进程总共发送了500次SIGINT信号给rcv进程,但是实际过程中rcv只接受/处理了1

辛星浅析Linux中的信号

要说Linux中的信号,不得不先提一下中断这个概念.中断是系统中对于异步事件的响应,也就是说某个进程可以在代码执行的过程中被打断了,它先去执行一段异常处理程序.中断可以分为硬件中断,也就是外部中断,它是由外部设备通过硬件请求的方式产生的中断.而软件中断,也就是内部中断,它是由CPU运行程序的一些错误或者执行内部程序调用的时候引起的一种中断. 在CPU的层面去看中断,是这样的一个步骤: ①中断源发出中断信号  ②CPU判断是屏蔽该中断以及现场保护③CPU查询中断向量表,找到相应服务程序的入口地址,

Linux 中常见信号介绍

http://blog.csdn.net/eager7/article/details/8290937 我们运行如下命令,可看到Linux支持的信号列表: $ kill -l1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR213) SIGPIPE 14) SIGALRM 15) SIGTER

浅析Linux中的信号机制(一)

有好些日子没有写博客了,自己想想还是不要荒废了时间,写点儿东西记录自己的成长还是百利无一害的.今天是9月17号,暑假在某家游戏公司实习了一段时间,做的事情是在Windows上用c++写一些游戏英雄技能的逻辑实现.虽然时间不算长,但是也算学了一点东西,对团队项目开发流程也有了一个直观的感受,项目里c++11新特性也有用到不少,特别是lambda表达式,STL的一些容器和算法也终于有了可以实践的地方.由于自己比较喜欢Linux C,也就没有做留下的打算,现在回到了学校,好好复习一段时间,准备一下校招

Linux 信号signal处理机制(ZZ)

http://www.cnblogs.com/taobataoma/archive/2007/08/30/875743.html 信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使用信号,以及有关信号的几个系统调用. 信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断.从它的命名可以看出,它的实质和使用很象中断.所以,信号可以说是进程控制的一部分. 一.信号的基本概念 本节先介绍信号的一些基本概念,然后

linux中的signal机制(转)

信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使用信号,以及有关信号的几个系统调用. 信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断.从它的命名可以看出,它的实质和使用很象中断.所以,信号可以说是进程控制的一部分. 一.信号的基本概念 本节先介绍信号的一些基本概念,然后给出一些基本的信号类型和信号对应的事件.基本概念对于理解和使用信号,对于理解信号机制都特别重要.下面就来看看什么是信号. 1.基本

Linux 信号signal处理机制

信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使用信号,以及有关信号的几个系统调用. 信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断.从它的命名可以看出,它的实质和使用很象中断.所以,信号可以说是进程控制的一部分. 一.信号的基本概念 本节先介绍信号的一些基本概念,然后给出一些基本的信号类型和信号对应的事件.基本概念对于理解和使用信号,对于理解信号机制都特别重要.下面就来看看什么是信号. 1.基本

Linux内核中的信号机制--一个简单的例子【转】

本文转载自:http://blog.csdn.net/ce123_zhouwei/article/details/8562958 Linux内核中的信号机制--一个简单的例子 Author:ce123(http://blog.csdn.NET/ce123) 信号机制是类UNIX系统中的一种重要的进程间通信手段之一.我们经常使用信号来向一个进程发送一个简短的消息.例如:假设我们启动一个进程通过socket读取远程主机发送过来的网络数据包,此时由于网络因素当前主机还没有收到相应的数据,当前进程被设置

Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)

整理自网络 Unix IPC包括:管道(pipe).命名管道(FIFO)与信号(Signal) 管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信: 实现机制: 管道是由内核管理的一个缓冲区,相当于我们放入内存中的一个纸条.管道的一端连接一个进程的输出.这个进程会向管道中放入信息.管道的另一端连接一个进程的输入,这个进程取出被放入管道的信息.一个缓冲区不需要很大,它被设计成为环形的数据结构,以便管