1.Linux内核信号通信概述
Linux进程间的信号通信,同样需要在内核中进行,内核存在多种信号,不同于管道通信的是,管道通信需要去用户空间告诉内核,让内核来创建一个通信对象,信号通信的对象已经存在而且有很多对象。可以用kill -l命令去查询,可以查到Linux有多达64种信号。
2.信号的处理
1,捕捉(收到某个信号,做指定的动作,而不是做默认的)
2,忽略(收到某个信号,不做什么动作)
3,阻塞(收到某个信号,先做完当前事情,然后在响应信号)
4,按照默认动作
注:SIGKILL,SIGSTOP不能被捕捉
3.信号通信常用函数
信号的发送:kill raise alarm
信号的接收:pause() sleep while(1)
信号的处理:signal
3.1信号的发送
进程可以通过kill函数向包括它本身在内的其他进程发送一个信号,如果程序没有发送这个信号的权限,对kill函数的调用就将失败,而失败的常见原因是目标进程由另一个用户所拥有。
所需头文件 |
#include<signal.h> #include<sys/types.h> |
|
函数原型 |
Int kill(pid_t pid, int sig); |
|
函数传入值 |
pid: |
正数:要接收信号的进程号 |
0:信号被发送到所有和pid进程在同一个进程组的进程 |
||
-1:信号发送给所有进程表钟的进程(除了进程号最大的进程除外) |
||
sig:信号 |
||
函数返回值 |
成功:0 |
|
失败:-1 |
raise:发送信号给自己 == kill(getpid(),sig)
所需头文件 |
#include<signal.h> #include<sys/types.h> |
函数原型 |
Int raise(int sig); |
函数参数 |
sig:信号 |
函数返回值 |
成功:0 |
出错:-1 |
alarm函数与raise函数比较:
相同点:让内核发送信号给当前进程
不同点:
1.alarm只会发SIGALARM信号
2.alarm会让内核定时一段时间之后发送信号,raise会让内核立刻发送信号
所需头文件 |
#include<unidtd.h> |
函数原型 |
unsigned int alarm(unsigned int seconds) |
函数参数 |
seconds: 指定秒数 |
函数返回值 |
成功:如果调用alarm()前,进程中已经设置了闹钟时间则返回上一个闹钟时间剩余的时间,否则返回0, |
出错:-1 |
注意:一个进程只能有一个闹钟时间。如果在调用alarm时已设置过闹钟时间,则之前的闹钟时间被新值所代替
3.2信号接收:
接收信号的进程有的条件:想要使接收的进程能接收到信号,这个进程不能结束,比如调用sleep()、pause()函数,或者让使用while(1)让程序不退出。
pause函数
所需头文件 |
#include<unidtd.h> |
函数原型 |
int pause(void) |
函数功能 |
使调用进程(线程)进入休眠状态(就是挂起);直到接收到信号且信号函数成功返回 pause函数才会返回 |
函数返回值 |
成功:0,出错:-1 |
信号函数
Linux的64种信号里面,大部分的默认处理是推出进程,很多时候我们并不想按照默认的方式处理,而是想要按照我们定义的方式执行。
所需头文件 |
#include<signal.h> |
|
函数原型 |
void(* signal(int signum,void(*handler)(int)))(int); |
|
函数参数 |
signum:指定信号 |
|
handler |
SIG_IGN:忽略该信号 |
|
SIG_DFL:采用系统默认方式处理信号 |
||
自定义的信号函数处理函数指针 |
||
函数返回值 |
成功:设置之前的额信号处理方式 |
|
出错:-1 |
4.Linux常用信号解释
信号名 |
含义 |
默认操作 |
SIGHUP |
该信号在用户终端连接(正常或非正常)结束时发出,通常是在终端的控制进程结束时,通知同一会话内的各个作业与控制终端不在关联。 |
终止 |
SIGINT |
程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出,用于通知前台进程组终止进程 |
终止 |
SIGQUIT |
该信号和SIGINT类似,但由QUIT字符(通常是Ctrl-\)来控制。 |
终止 |
SIGILL |
该信号在一个进程企图执行一条非法指令时(可执行文件本身出现错误,或者试图执行数据段、堆栈溢出时)发出 |
终止 |
SIGFPE |
该信号在发生致命的算术运算错误时发出。这里不仅包括浮点运算错误,还包括溢出及除数为0等其他所有的算术的错误。 |
终止 |
SIGKILL |
该信号用来立即结束程序的运行,并不能被阻塞、处理和忽略。 |
终止 |
SIGALRM |
该信号当一个定时器到时的时候发出 |
终止 |
SIGSTOP |
该信号用于暂停一个进程,且不能被阻塞、处理或忽略。 |
暂停进程 |
SIGTSTP |
该信号用于暂停交互进程。用户可键入SUSP字符(通常是Ctrl-z)发出这个信号。 |
暂停进程 |
SIGCHLD |
子进程改变状态时,父进程会受到这个信号。 |
忽略 |
SIGUSR1 |
留给用户用,用户自定义 |
终止 |
SIGUSR2 |
留给用户用,用户自定义 |
终止 |