C语言之捕捉信号

我们有时候需要在程序中做一些对于用户或内核发出的信号后的处理,如写回文件等善后处理的事情,或者直接忽略信号(当你按Ctrl+C时我压根不理你)。下面是一段信号处理的代码(POSIX C):

int catch_signal(int sig,void (*handler)(int)){
    struct sigaction action;//<signal.h>
    action.sa_handler=handler;
    sigemptyset(&action.sa_mask);//用掩码来过滤sigaction要处理的信号
    action.sa_flags=0;
    return sigaction(sig,&action,NULL);//第二个参数为新的action的地址,第三个参数为被替换的旧action,如果不想保存(使用)旧的action,就设为NULL
}
void myfun(int sig){//这个函数是自定义用来针对该信号处理事务的,注意参数的返回值
    puts("Goodby the cruel world!
");
    exit(1);
}

下面可以在主函数中使用:

if(catch_signal(SIGINT,myfun)==-1){
    fprintf(stderr,"Can't map the handler");
    exit(2);
}

注意有两个信号不能被捕捉和忽略:SIGKILL(可以用kill -KILL 接PID产生)、SIGSTOP(暂停进程)

其他可被捕捉的信号有SIGFPE SIGTERM SIGQUIT SIGTRAP SIGWINCH SIGSEGV SIGPIPE.

最令人恐惧的恐怕是SIGSEGV吧,访问非法存储器地址,常见那句:段错误,核心已转储。(也许是连带SIGQUIT)。

程序中可以使用raise(int sig)在信号处理函数中就收到低级别的信号时引发更高级别的信号(称作信号升级)。

小记:

想起昨天写了一个小程序,运行时加&让其后台运行,但要将其关掉时可犯了难(不知该用哪个命令又快又好),普通情况下在某个终端启动的程序应该是该终端的一个子进程(启动时不加&),关掉终端那么终端的子进程也随之亡去。可我的程序让其后台运行,关掉启动它的终端,程序并没有终止,感觉像守护进程似的,也许这时候我的程序的直接父进程变成了init进程。

通过ps -aux | grep myProgram 或者pgrep,jobs等 找到进程的pid,再kill掉,或者直接pkill掉。

原文地址:https://www.cnblogs.com/makefile/p/catch-signal.html