信号(signal)机制是unix系统中较为古老的进程间通讯机制,很多条件可以产生一个信号:
1、当用户按下某些按键时,产生信号。
2、硬件异常产生信号。
3、进程使用kill函数将信号发给另一个进程。
4、用户使用kill命令将信号发送给其他进程。
信号的类型
常用的信号
当某信号出现时,将按照下列三种方式中的一种进行处理:
1、忽略此信号
大多数信号都按照这种方式进行处理,但有两种信号却决不能被忽略。它们是:SIGKILL和SIGSTOP。这两种信号不能被忽略的原因是:它们向超级用户提供了一种终止或停止进程的方法。
2、执行用户希望的动作
通知内核在某种信号发生时,调用一个用户函数。在用户函数中,执行用户希望的处理。
3、执行系统默认动作
对大多数信号的系统默认动作是终止该进程。
信号发送
发送信号的主要函数有kill和raise
区别:kill既可以向自身发送信号,也可以向其他进程发送信号。而raise函数是向进程自身发送信号。
函数原型:
#include <sys/types.h>
#include <signal.h>
int kill(pid_t,int signo)
int raise(int signo)
kill的pid 参数有四种不同的情况:
闹钟时间
使用alarm函数可以设置一个闹钟时间,在设置时间到了的时候,会发出一个SIGALRM信号,如果进程不捕捉这个信号,那么这个进程就会被终止。
函数原型:
#include <unistd.h>
unsigned int alarm(unsigned int seconds)
经过seconds秒后就会发出SIGALRM信号。
注意:1、每个进程只能有一个闹钟时间。如果在调用alarm时,以前已为该进程设置过闹钟时间,而且它还没有超时,以前登记的闹钟时间则被新值替代。
2、如果有以前登记的尚未超过的闹钟时间,而这次seconds值是0,则表示取消以前的闹钟。
挂起函数
使用pause函数使调用进程挂起直到捕捉到一个信号
函数原型:
#include <unistd.h>
int pause(void)
只有执行了一个信号处理函数后,挂起才结束。
信号的处理
1、当系统捕捉到某个信号时,可以忽略该信号或是使用指定的处理函数来处理该信号,或者使用系统默认的方式。
2、信号处理的主要方式有两种,一种是使用简单的signal 函数,另一种是使用信号集函数组。
signal函数
实际使用
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <signal.h>
5
6 void func(int signal_no)
7 {
8 if (signal_no == SIGINT) {
9 printf("this is a SIGINT signal\n");
10 }
11 if (signal_no == SIGQUIT) {
12 printf("this is a SIGQUIT signal\n");
13 }
14 }
15
16 int main(int argc, char **argv)
17 {
18 signal(SIGINT, func); //注册函数
19 signal(SIGQUIT, func);
20
21 pause(); //将进程挂起
22
23 return 0;
24 }
效果
在键盘上按下ctrl+c就会产生SIGINT信号
在键盘上按下ctrl+\就会产生SIGQUIT信号