signal信号机制是属于计算机异常处理机制中的一种。
signal信号属于一种异步处理异常的机制之一。
类似于我们平常在命令行上对于死循环的程序,按下ctrl-z暂时挂起,ctrl-c程序终止,这些挂起,终止信号都属于signal信号的一种,常见的几种signal信号如下图所示(供查询使用,平时并无用):
信号常见的术语:
1.发送信号:
先简单介绍一下进程组的概念,一个操作系统有很多进程所组成,有系统进程,应用进程。而这些进程又是以进程组来区分的。Shell里面又有前台进程组和后台进程组,前台进程组说明shell进程必须等待前台进程结束才可以读取并执行下一条指令,后台进程组顾名思义在后台进行。父进程与它的子进程处于同一进程组中,在shell上每次发送类似ctrl-c的信号都会发送到每个前台进程组中。
以下图片说明进程组的概念:
发送信号常用的两种方法;
通过/bin/kill程序发送信号:
/bin/kill -9 15213
发送信号给进程15213
/bin/kill -9 -15213
如果进程前面表示为负的,说明发送信号9给15213进程组的所有信号
还有一个同名函数也可以在程序中对指定进程发送信号:
#include<sys/type.h>
#include<signal.h>
int kill(pid_t pid, int sig);
从键盘发送信号
Unix用作业(job)这个抽象概念来表示对一个命令行求值而创建的进程。在任何时刻,至多只有一个前台进程和0个或多个后台进程,而ctrl-z或者ctrl-c则会向每一个前台进程发送信号。
通过alarm函数给自身进程发送信号
alarm的函数原型:
#include<unistd.h>
unsigned int alarm(unsigned int secs);
//返回:前一次闹钟剩余的秒数,若以前没有闹钟,则设置为0
该函数即是为了到了设置的固定时间发送一次信号消息
接受消息
接受消息的时候,通常会设置一个handler函数,表示自定义收到消息后的行为该如何
前面都是些对signal介绍,接下来到了重点和难点了呀!!!
信号处理问题
一个程序接受一个信号的时候似乎很好理解,且不会出现太大的问题,但是一旦一个进程接受了多个信号的时候,问题就出现了
以下是问题的说明:
该信号如果理解成现实生活中的信号,现实中的信号也永远是异步。例如,小张和小和正在说话,这是一个顺序执行的操作。如果,这时候上司(操作系统内核)突然说了声“小张,那个文件给我处理一下了”,这就是一个异步信号,小张在接受这个信号之后就会去处理这个文件,这个就是信号处理函数,如果上司说了“那个文件给我处理一下”,这时候另一个同事说“一起去吃饭”,这时候就有两个信号了,这时候小张就先去“处理文件”的信号,再去处理“一起去吃饭”的信号,这就是待处理信号被阻塞。如果上司一直说“那个文件给我处理一下”,“那个文件给我处理一下”,这就是相同类型的信号有很多个,这时候只有第一个有用,小张就去做第一个,这就是待处理信号不会排队等待的道理
- 待处理信号被阻塞:Unix信号函数会阻塞统一类型的待处理信号。就比如,一个程序接受了一个SIGCHLD的信号,那么在执行SIGCHLD的信号的时候,下一的SIGCHLD的信号就会被阻塞,成为待处理信号。
- 待处理信号不会排队等待。即针对同一类型的信号,只能有一个待处理信号。例如,一个进程接受了一个SIGCHLD的信号,在执行SIGCHLD的信号处理程序的时候,来了两个SIGCHLD信号,那么只有一个SIGCHLD会成为待处理信号。
- 系统调用可以被中断。像read,wait,accept这样的系统调用潜在地会阻塞进程一段时间,称为慢速系统调用。在某些系统中,当处理程序捕获到一个信号,被中断的系统调用在信号处理程序进行后不再返回,而是立即返回给用户一个错误条件,并将errn