现在的位置: 首页 > 综合 > 正文

《深入理解计算机系统》第八章 (四)信号

2019年07月18日 ⁄ 综合 ⁄ 共 1513字 ⁄ 字号 评论关闭

信号是软件层面上的异常

(一)Linux信号

可以通过man 7 signal 查看Linux提供的标准信号。其中描述的信号的编号在不同的处理器体系结构的差异有所不同。

(二)信号传送的步骤

传送一个信号到目的进程通常由两个不同的步骤组成:

(1)发送信号

发送信号的原因:

a)内核检测到一个系统事件

b)一个进程调用了kill函数,显式地要求内核发送一个信号给目的进程。

内核通过更新目的进程的上下文的某个状态,发送一个信号给目的进程

发送信号的方式:

a)通过/bin/kill程序发送信号

b)通过键盘发送

常用的与键盘相关的信号:

SIGINT :来自键盘的终端信号(CTRL+C)

SIGQUIT:来自键盘的退出信号(CTRL +\)

SIGSTOP:来自键盘(CTRL+Z)或调试程序的停止信号

c)通过kill函数发送

函数原型如下:

#include<sys/type.h>

#include<signal.h>

int kill(pid_t pid , int sig);

如果pid大于0,则给进程pid 发送信号sig,如果pid小于0,则给abs(pid)进程组中的每个进程发送信号sig。如果pid等于0,则不发送信号

d)通过alarm函数发送

alarm - set an alarm clock for delivery of a signal

#include <unistd.h>

unsigned int alarm(unsigned int seconds);

alarm()  arranges  for  a SIGALRM signal to be delivered to the calling process in seconds seconds.

(2)接收信号

当目的进程被内核强迫以某种方式对信号的发送做出反应时,目的进程就接收了信号。

内核为每个进程在pending位向量中维护着待处理信号的集合,在blocked位向量中维护着被阻塞的信号集合,传送一个类型为k的信号,内核就会设置pending中的k位,接受一个类型为k的信号,内核就会清除pending中的k位。

每个信号类型都有一个预定义的默认行为,是如下当中的一种:

a)进程终止

b)进程终止并转储存储器

c)进程停止直到被SIGCONT信号重启

d)进程忽略该信号

进程可以通过signal函数修改和信号相关联的默认行为,SIGSTOP和SIGKILL两个信号的默认行为是不能修改的。

 #include <signal.h>

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

signum的值为:SIG_IGN,则忽略类型为signum的信号

signum的值为:SIG_DFL,则类型为signum的信号行为恢复为默认行为

signum的值为:其他值,则设置类型为signum的信号的行为是用户定义的函数(信号处理程序)。只要进程接收到一个类型为signum信号,就调用这个程序

信号处理问题分析的三大要点

(1)待处理信号被阻塞

假设一个进程捕获了一个类型为k的信号,且当前正在运行它的信号处理程序,则如果另外一个类型为k的信号传递给这个进程,则这个类型为k的信号将变成待处理的,不会被接收,直到处理程序返回。

(2)待处理信号不会排队

任意类型的信号,最多只能有一个待处理的信号,所以当上面描述的已经有一个类型为k的待处理信号的时候,后续的传递到这个进程的待处理信号都将被直接丢弃。

(3)系统调用可以被中断

在某些系统中当处理程序捕捉到一个信号时,被中断的慢速系统调用在信号处理程序返回时将不再继续,而是立即返回一个错误条件,并设置errno为EINTR。

抱歉!评论已关闭.