信号
信号是一种向进程发送通知,告诉其某件事情发生了的一种简单通信机制。
信号的产生:
另一个进程发送信号
内核发送信号
底层硬件发送信号
在命令行执行kill -l,可以显示所有的信号列表。
其中,常用信号为:
信号宏名 | 信号编号 | 说明 | 系统默认处理方式 |
---|---|---|---|
SIGABRT | 6 | 终止进程,调abort函数时产生 | 终止,产生core文件 |
SIGALRM | 14 | 超时,调用alarm函数时产生 | 终止 |
SIGBUS | 7 | 硬件故障 | 终止,产生core文件 |
SIGCHLD | 17 | 子进程状态改变 | 忽略 |
SIGINT | 2 | 终止进程(ctrl+c) | 终止 |
SIGIO | 29 | 异步通知信号 | 终止 |
SIGKILL | 9 | 无条件终止一个进程,不可以被捕获或忽略 | 终止 |
SIGPIPE | 13 | 写没有读权限的管道文件时 | 终止 |
SIGPOLL | 8 | 轮询事件,涉及POLL机制 | 终止 |
SI |
信号发送
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid,int sig);//kill命令就是调用这个函数来实现
kill()可以用来传送sig指定的信号给参数pid指定的进程。参数pid有集中情况:
pid>0 将信号传给进程识别码为pid的进程。
pid=0 将信号传给和目前进程相同进程组的所有进程。
pid=-1 将信号像广播般传送给系统内所有的进程。
pid<0 将信号传给进程组识别码为pid绝对值的所有进程。
返回值:执行成功返回0,失败返回-1。
#include <signal.h>
int raise(int sig);
raise()用来将参数sig指定的信号传送给目前的进程。相当于kill(getpid(),sig);
返回值:执行成功返回0,失败返回非0.
功能:
1)kill:向PID所指向的进程发送指定的信号 。
2)raise:向当前进程发送指定信号。
返回值:
1)kill:成功返回0,失败返回-1,errno被设置
2)raise:成功返回0,失败返回非0.
#include <unistd.h>
#include <signal.h>
unsigned int alarm(unsigned int seconds);
alarm()用来设置信号SIGALRM在经过参数seconds指定的秒数后传送给目前的进程。如果参数seconds为0,则之前设置的闹钟会被取消,并将剩下的时间返回。
返回值:返回之前闹钟的剩余秒数,如果之前未设闹钟则返回0。
#include <stdlib.h>
void abort();//以异常方式结束进程
abort()将引起进程异常的终止,此时所有已打开的文件流会自动关闭,所有的缓冲区数据也会自动写回。
信号处理的方式
忽略
执行用户需要执行的动作(捕获)
默认处理
信号处理API
#include <signal.h>
typedef void(*sighandler_t)(int);
sighandler_t signal(int signum,sighandler_t handler);
功能:
设置某个信号的处理方式。
处理方式可以被设置为忽略、捕获、默认。
进程的进程表(task_struct)中会有一个“信号处理方式登记表”,专门用于记录信号的处理方式,调用signal函数设置某个信号的处理方式时,会将信号的处理方式登记到该表中。
每个进程拥有独立的task_struct结构体变量,因而每个进程的“信号处理方式登记表”都是独立的,所以每个进程对信号的处理方式自然也是独立的,互不干扰。
参数:
1)signal:信号编码
2)handler:信号处理方式
sighandler_t是被typedef后的类型,原类型void(*)(int),这是一个函数指针类型。
sighandler_t handler也有直接写出void(*handler)(int)。
sighandler_t signal(int signum,void(*handle)(int));( a )忽略:SIG_IGN
( b )默认:SIG_DFL
( c )捕获:填写类型为viod(*)(int)的捕获函数地址,当信号发生时,会自动调用捕获函数来进行相应的处理。