kill -l 列出所有信号
建立在早期的信号处理机制上(1-31) 是不可靠信号。
不支持排队,可能会丢失,同一个信号如果连续产生多次。进程可能只接收到一次。
建立在新信号处理机制上(34-64)是可靠信号,支持排队,不会丢失。
信号来源
硬件异常:除0,无效访问,未定义指令,总线错误,软件异常
软件异常:
信号捕获:
typedef void(*sighanler_t)(int);
功能:信号处理函数的格式
sighandler_t signal(int signum,sighandler_t handler);
功能:相信号注册一个信号处理函数
signum:信号编号
handler:函数指针 或者SIG_IGN SIG_DFL
SIG_IGN :忽略
SIG_DFL: 按默认处理。
返回值:成功返回函数指针,失败返回NULL
子进程会继承父进程的信号处理方式,但如果是通过exec系列函数创建的子进程,会恢复默认的信号处理方式
信号的发送:键盘:ctrl+c ctrl+\ ctrl+z
错误:除0,非法内存访问,硬件故障,总线错误
命令:kill 信号 进程号 或 killall 信号 进程名
函数: int kill(pid_t pid,int sig);
向某进程发送信号
pid:进程号
sig:信号
int raise(int sig);
向自己发送信号
void abort(void);
功能:向进程自己发送SIGABRT信号
unsigned int alarm(unsigned int seconds);
功能:让内核在一段时间后向进程发送SIGALARM信号
返回值:上次alarm设置的剩余时间
信号集和信号阻塞:
信号集:是一种数据类型,可以存储多个信号
sigset_t 128二进制,每一位都代表一个信号
相关函数:
int sigemptyset(sigset_t *set);
功能:清空信号集
int sigismember(sigset_t *set)
功能:测试信号集中有哪些信号。
返回值:0 不存在
1 存在
-1 信号非法
信号阻塞:
当程序在执行一些特殊操作时是不适合处理信号的,此时可以让内核先屏蔽信号,等操作执行完成后再发送信号
当信号产生时,内核会在其所维护信号表中为进程设置一个与该信号对应的标记,这个过程叫递送。从信号产生到完成递送有个时间间隔,处于这个间隔的信号状态叫未决。
信号屏蔽就是让信号先处于未决状态,暂停递送。屏蔽解除时再继续递送
int sigprocmask(int how,const sigset_t *set,sigset_t *oldset);
功能:设置要屏蔽的信号,这些信号存储在信号集里面。
how:
SIG_BLOCK 把set中的信号添加到要屏蔽的信号集中
SIG_UNBLOCK 从信号集删除set的信号
SIG_SETMASK 用set替换之前的信号集。
set:准备好的信号集
oldset:原本的信号集