Linux-信号机制详解(一)

之前有写过SystemV的信号量机制,现在是信号。这里的信号和前面的信号量是不同的。这里的信号是进程给操作系统或进程的某种信息,让操作系统或者其他进程做出某种反应。

信号是进程间通信机制中唯一的异步通信机制,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。进程之间可以互相通过系统调用kill发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。信号机制除了基本通知功能外,还可以传递附加信息。

在这里举几个常见的信号的例子:

1. 用户输入命令,在Shell下启动一个前台进程。

2. 用户按下Ctrl-C,这个键盘输入产生一个硬件中断。

3. 如果CPU当前正在执行这个进程的代码,则该进程的用户空间代码暂停执行,CPU从用

户态 切换到内核态处理硬件中断。

4. 终端驱动程序将Ctrl-C解释成一个SIGINT信号,记在该进程的PCB中(也可以说发送了

一 个SIGINT信号给该进程)。

5. 当某个时刻要从内核返回到该进程的用户空间代码继续执行之前,需先处理PCB中记

录的信号,发现有一个SIGINT信号待处理,用这个信号的默认处理动作是终止进程,所

以直接终止进程而不再返回它的用户空间代码执行。

前台进程在运行过程中用户随时可能按下Ctrl-C键产生一个信号,也就是说该进 程的用户空间代码执行到任何地值都有可能收到SIGINT信号而终止,所以信号相对于进程的控制流 程来说是异步(Asynchronous)的。

一。信号种类:

Linux的signal.h中定义了很多信号,使用命令kill -l  可以查看系统定义的信号列表:

可以发现其实没有32,33号信号。1-31号信号叫做普通信号,34-64号信号叫做实时信号。

通过指令      kill  信号序号  进程号   可以向一个进程发送信号

二。信号产生的条件:

1. 用户在终端按下某些键时,终端驱动程序会发送信号给前台进程,例如Ctrl-C产生SIGINT信号,Ctrl-\产生SIGQUIT信号,Ctrl-Z产生SIGTSTP信号(可使前台进程停止)

SIGINT的默认处理动作是终止进程,SIGQUIT的默认处理动作是终止进程并且Core Dump,所以我们可以写一个死循环,让后通过对这个进程发送SIGINT(ctrl-C)SIGQUIT(ctrl-\)信号来终止这进程。

可以看到进程被终止了,ctrl-C好像不行。。。。

解释一下CoreDump:

当一个进程要异常终止时,可以选择把进程的用户空间内存数据全部 保存到磁盘上,文件名通常是core,这叫做Core Dump。进程异常终止通常是因为有Bug,例如非法内存访问致段错误,事后可以用调试器检查core文件以查清错误原因,这叫做Post-mortem Debug。这个进程允许产生多个的core问件取决于进程的Resource Limit(这个信息保存 在PCB中)。默认是不允许产生core问件的,因为core文件中可能包含用户密码等敏感信息,不安全。在开发调试阶段可以用ulimit命令改变这个限制,允许产生core文件。

2. 硬件异常产生信号,这些条件由硬件检测到并通知内核,然后内核向当前进程发送适当的信号。例如当前进程执行了除以0的令,CPU的运算单元会产生异常,内核将这个异常解释 为SIGFPE信号发送给进程。再如当前进程访问了非法内存地址,,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。

首先在后台执行死循环程序,然后用kill命令给它发SIGSEGV信号。通过在可执行文件后面加一个&,将进程放到后台运行:

可以看到进程被杀死。

kill命令是调?kill函数实现的。 kill函数可以给?个指定的进程发送指定的信号。

raise函数可 以给当前进程发送指定的信号(自己给自己发信号)。

<span style="font-family:Microsoft YaHei;font-size:14px;">#include <signal.h>
int kill(pid_t pid, int signo);
int raise(int signo);</span>

这两个函数都是成功返回0,错误返回-1。

abort函数使当前进程接收到SIGABRT信号时异常终止。

<span style="font-family:Microsoft YaHei;font-size:14px;">#include <stdlib.h>
void abort(void);</span>

就像exit函数一样,abort函数总是会成功的,所以没有返回值。

3. 一个进程调用kill(2)函数可以发送信号给另一个进程。 可以用kill(1)命令发送信号给某个进程,kill(1)命令也是调用kill(2)函数实现的,如果不明确指定信号则发送SIGTERM信号,该信号的默认处理动作是终止进程。 当内核检测到某种软件条件发生时也可以通过信号通知进程,例如闹钟超时产生SIGALRM信号,向读端已关闭的管道写数据时产生SIGPIPE信号。 如果不想按默认动作处理信号,用户程序可以调用sigaction(2)函数告诉内核如何处理某种信号

可选的处理方式有三种:

(一)忽略此信号。

(二)执行该信号的默认处理动作。

(三)提供一个自定义的信号处理函数要求内核在处理该信号时切换到用户态执行这个处理函数,这种方 式称为捕捉(Catch)一个信号。

例:

SIGPIPE是一种由软件条件产生的信号

<span style="font-family:Microsoft YaHei;font-size:14px;">#include <unistd.h>
unsigned int alarm(unsigned int seconds);</span>

调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号, 该信号的默认处理动作是终止当前进程。 这个函数的返回值是0或者是以前设定的闹钟时间还余下 的秒数。打个比方,某人要睡觉,设定闹钟为30分钟之后响,20分钟后被吵醒了,还想多睡 一会儿,于是重新设定闹钟为15分钟之后响,“以前设定的闹钟时间还余下的时间”就是10分钟。如果seconds值为0,表?取消以前设定的闹钟,函数的返回值仍然是以前设定的闹钟时间还余下的秒数。

这个程序的作用是1秒钟之内不停地数数,1秒钟到了就被SIGALRM信号终止。

三。阻塞信号

实际执?信号的处理动作称为信号递达(Delivery),信号从产?到递达之间的状态,称为信号未决(Pending)。进程可以选择阻塞(Block )某个信号。被阻塞的信号产?时将保持在未决状态,直到进程解除对此信号的阻塞,才 执?递达的动作。
注意,阻塞和忽略是不同的只要信号被阻塞就不会递达,?忽略是在递达之后 可选的?种处理动作。信号在内核中的表?可以看作是这样的:

结合处理信号的三种方式:

1. SIGHUP信号未阻塞也未产?过,当它递达时执?默认处理动作。

2. SIGINT信号产?过,但正在被阻塞,所以暂时不能递达。虽然它的处理动作是忽略,但在没 有解除阻塞之前不能忽略这个信号,因为进程仍有机会改变处理动作之后再解除阻塞。

3. SIGQUIT信号未产?过,?旦产?SIGQUIT信号将被阻塞,它的处理动作是?户?定义函数sighandler。

常规信号在递达之前产?多次只计?次,?实时信号在递达之前产?多次可以依次放在?个队列?。因此,未决和阻塞标志可以?相同的数据类型sigset_t来存储,sigset_t称为信号集,这个类型可以表?每个信号的“有效”或“?效”状态,在阻塞信号集中“有效”和“?效”的含义是该信号是否被阻塞,?在未决信号集中“有效”和“?效”的含义是该信号是否处于未决状态。

(一)信号集操作函数

调?以下函数来操作sigset_t变量

#include <signal.h>
int sigemptyset(sigset_t *set);?
int sigfillset(sigset_t *set);?
int sigaddset(sigset_t *set, int signo);?
int sigdelset(sigset_t *set, int signo);?
int sigismember(const sigset_t *set, int signo);

(二)信号屏蔽字

调?函数sigprocmask可以读取或更改进程的信号屏蔽字(阻塞信号集)。

#include <signal.h>?
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);

返回值:若成功则为0,若出错则为-1

如果oset是?空指针,则读取进程的当前信号屏蔽字通过oset参数传出。如果set是?空指针,则 更改进程的信号屏蔽字,参数how指?如何更改。如果oset和set都是?空指针,则先将原来的信号 屏蔽字备份到oset?,然后根据set和how参数更改信号屏蔽字。假设当前的信号屏蔽字为mask,下表说明了how参数的可选值。

如果调?sigprocmask解除了对当前若?个未决信号的阻塞,则在sigprocmask返回前,?少将其中 ?个信号递达

(三)未决信号集

#include <signal.h>
int sigpending(sigset_t *set);

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

时间: 2024-12-30 05:51:34

Linux-信号机制详解(一)的相关文章

LINUX 信号概念详解

LINUX 信号概念详解 我们运行如下命令,可看到Linux支持的信号列表: # kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP

Linux RCU 机制详解

1.简介: RCU(Read-Copy Update)是数据同步的一种方式,在当前的Linux内核中发挥着重要的作用. RCU主要针对的数据对象是链表,目的是提高遍历读取数据的效率,为了达到目的使用RCU机制读取数据的时候不对链表进行耗时的加锁操作.这样在同一时间可以有多个线程同时读取该链表,并且允许一个线程对链表进行修改(修改的时候,需要加锁). 2.应用场景: RCU适用于需要频繁的读取数据,而相应修改数据并不多的情景,例如在文件系统中,经常需要查找定位目录,而对目录的修改相对来说并不多,这

Linux RCU机制详解

关于rcu的几点声明: 1:RCU使用在读者多而写者少的情况.RCU和读写锁相似.但RCU的读者占锁没有任何的系统开销.写者与写写者之间必须要保持同步,且写者必须要等它之前的读者全部都退出之后才能释放之前的资源. 2:RCU保护的是指针.这一点尤其重要.因为指针赋值是一条单指令.也就是说是一个原子操作.因它更改指针指向没必要考虑它的同步.只需要考虑cache的影响. 3:读者是可以嵌套的.也就是说rcu_read_lock()可以嵌套调用. 4:读者在持有rcu_read_lock()的时候,不

linux信号机制分析

[摘要]本文分析了Linux内核对于信号的实现机制和应用层 的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核对于信号的处理流程包括信号的触发/注册/执行 及注销等.最后介绍了应用层的相关处理,主要包括信号处理函数的安装.信号的发送.屏蔽阻塞等,最后给了几个简单的应用实例. [关键字]软中断信号,signal,sigaction,kill,sigqueue,settimer,sigmask,sigprocmask,sigset_t 1      

LINux网络的NAPI机制详解一

在查看NAPI机制的时候发现一篇介绍NAPI引入初衷的文章写的很好,通俗易懂,就想要分享下,重要的是博主还做了可以在他基础上任意修改,而并不用注明出处的声明,着实令我敬佩,不过还是附上原文链接! http://blog.csdn.net/dog250/article/details/5302853 处理外部事件是cpu必须要做的事,因为cpu和外设的不平等性导致外设的事件被cpu 当作是外部事件,其实它们是平等的,只不过冯氏机器不这么认为罢了,既然要处理外部事件,那么就需要一定的方法,方法不止一

Android内存管理机制详解 (zhuan)

http://www.2cto.com/kf/201212/175786.html 与windows内存区别 在Linux中经常发现空闲内存很少,似乎所有的内存都被系统占用了,表面感觉是内存不够用了,其实不然.这是Linux内存管理的一个优秀特性,在这方面,区别于 Windows的内存管理.主要特点是,无论物理内存有多大,Linux都将其充份利用,将一些程序调用过的硬盘数据读入内存,利用内存读写的高速特性来提高Linux系统的数据访问性能.而Windows是只在需要内存时,才为应用程序分配内存,

Linux关机命令详解

在linux下一些常用的关机/重启命令有shutdown.halt.reboot.及init,它们都可以达到重启系统的目的,但每个命令的内部工作过程是不同的. Linux centos重启命令: 1.reboot 2.shutdown -r now 立刻重启(root用户使用) 3.shutdown -r 10 过10分钟自动重启(root用户使用) 4.shutdown -r 20:35 在时间为20:35时候重启(root用户使用) 如果是通过shutdown命令设置重启的话,可以用shut

红帽Linux故障定位技术详解与实例(2)

红帽Linux故障定位技术详解与实例(2) 2011-09-28 14:26 圈儿 BEAREYES.COM 我要评论(0) 字号:T | T 在线故障定位就是在故障发生时, 故障所处的操作系统环境仍然可以访问,故障处理人员可通过console, ssh等方式登录到操作系统上,在shell上执行各种操作命令或测试程序的方式对故障环境进行观察,分析,测试,以定位出故障发生的原因. AD:2014WOT全球软件技术峰会北京站 课程视频发布 3.内核故障情形及处理 (1)内核panic panic是内

红帽Linux故障定位技术详解与实例(1)

红帽Linux故障定位技术详解与实例(1) 2011-09-28 14:26 圈儿 BEAREYES.COM 我要评论(0) 字号:T | T 在线故障定位就是在故障发生时, 故障所处的操作系统环境仍然可以访问,故障处理人员可通过console, ssh等方式登录到操作系统上,在shell上执行各种操作命令或测试程序的方式对故障环境进行观察,分析,测试,以定位出故障发生的原因. AD:2014WOT全球软件技术峰会北京站 课程视频发布 红帽Linux故障定位技术详解与实例是本文要介绍的内容,主要

linux screen 命令详解

linux screen 命令详解 一.背景 系统管理员经常需要SSH 或者telent 远程登录到Linux 服务器,经常运行一些需要很长时间才能完成的任务,比如系统备份.ftp 传输等等.通常情况下我们都是为每一个这样的任务开一个远程终端窗口,因为它们执行的时间太长了.必须等待它们执行完毕,在此期间不能关掉窗口或者断开连接,否则这个任务就会被杀掉,一切半途而废了. 二.简介 GNU Screen是一款由GNU计划开发的用于命令行终端切换的自由软件.用户可以通过该软件同时连接多个本地或远程的命