概述
5 信号捕获
信号的产生是异步事件,进程不知道信号何时会递送,也不会等待信号到来。
进程可以为信号注册信号处理函数来实现自定义动作。
进程的信号在内核态处理,内核为每个进程准备了一个信号向量表,记录每个信号所对应的处理机制。如果用户自定义了处理方式,则内核会使信号向量表中的指针指向新的信号处理函数。
Linux提供了两个捕获信号的函数:
- signal
- sigaction
5.1 signal函数
#include <signal.h>
typedef void(* sighandler_t)(int); //sighandler_t就是一个函数指针,指向的函数接受一个整型参数并返回一个无类型指针。加上typedef之后sighandler_t就是一种新的类型,就可以像int一样地去用它,不同的是它声明是一种函数指针
sighandler_t signal(int signum, sighandler_t handler);
函数功能:能实现信号屏蔽,但其主要功能仍为捕获信号,修改信号向量表中该信号的处理函数指针。
参数说明:
- signum:信号编号;
- handler:自定义信号处理函数的函数指针。
返回值说明:
- 成功:返回先前信号处理函数指针
- 不成功:返回SIG_ERR。
【案例1】为2号信号SIGINT设置自定义信号处理函数,并在信号处理函数中将信号恢复为默认处理函数。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
void sig_int(int paraSigno){ //自定义信号处理函数
printf("......catch you, SIGINTn");
signal(SIGINT, SIG_DEL); //信号处理函数执行
}//of sig_int
int main(){
signal(SIGINT, sig_int); //捕获信号SIGINT,修改信号处理函数
while(1); //等待信号递达
return 0;
}//of main
执行后使用组合键Ctrl+C或kill命令发送信号到当前进程,signal(SIGINT, SIG_DEL)恢复为默认处理函数后,程序将终止运行。
5.2 sigaction函数
#include <signal.h>
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
struct sigaction{
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask; //一个用于指定函数执行期间捕获屏蔽信号的位图
int sa_flags; //设置是否使用默认值,默认情况下,函数会屏蔽自己发送的信号,避免重新进入函数
void (*sa_restorer)(void);
};
函数功能:与signal相比,最大的优点是支持信息传递。
参数说明:
- signum:信号编号;
- act:传入参数,包含自定义信息处理函数和一些携带的参数;
- oldact:传出参数,包含旧的信息处理函数等信息。
返回值说明:
- 成功:0;
- 不成功:-1。
【案例2】使用sigaction函数修改2号信号SIGINT的默认动作。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
void sig_int(int paraSigno){
printf("......catch you, SIGINT, signo = %dn", paraSigno);
sleep(5); //模拟信号处理函数执行时间
}//of sig_int
int main(){
struct sigaction act, oldact;
act.sa_handler = sig_int; //修改信号处理函数指针
sigemptyset(&act.sa_mask); //初始化位图,表示不屏蔽任何信号
sigaddset(&act.sa_mask, SIGINT);//更改信号SIGINT的信号处理函数
act.sa_flags = 0; //设置flags屏蔽自身所发信号
sigaction(SIGINT, &act, &oldact);
while(1);
return 0;
}//of main
执行后使用组合键Ctrl+C或kill命令发送信号到当前进程,观察运行结果。
6 课后编程题
利用所学的信号处理函数实现sleep函数的功能。
最后
以上就是光亮荔枝为你收集整理的Linux编程基础 4.4:信号捕获的全部内容,希望文章能够帮你解决Linux编程基础 4.4:信号捕获所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复