先过我这一关 - signal
在运行程序的时候,一般都知道运行 Ctrl+C 八成就会把程序给中断,类似于应用程序里面的CLOSE ,但是如果有些数据在运行过程中没有保存,就会比较尴尬,此时就需要借助signal同学,让他对企图不小心中断程序时先去做一些操作,别直接退出,完成后再安全退出。
基本语法
c
//#include <signal.h>
//void (*signal(int sig, void (*func)(int)))(int);
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
signum
是需要处理的信号,比如SIGINT
(通常是Ctrl+C产生的中断信号)。handler
是一个指向函数的指针,这个函数的任务是处理信号。这个处理函数需要一个整型参数(信号的编号),返回信号的句柄,或者在出错时返回SIG_ERR
。
当信号 signum
被捕获时,系统将调用 handler
指向的函数。如果 hander
是 SIG_IGN
,则信号将被忽略;如果是 SIG_DFL
,则执行该信号的默认操作。
示例代码
下面是一个使用 signal
的示例,这段代码演示了如何捕获 SIGINT
信号,并定义一个简单的信号处理函数来处理用户的中断信号。
c
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void handle_sigint(int sig) {
printf("### \n");
printf("### Oops! You hit Ctrl+C! But I will not quit cause I am rnning. Signal %d received.\n", sig);
printf("### Save your work at first before close the application!!!\n");
printf("### \n");
}
int main() {
signal(SIGINT, handle_sigint);
while (1) {
printf("Program running... \n");
printf("Try press Ctrl+C to see can you stop me\n");
sleep(1);
}
return 0;
}
在这个程序中,signal
函数被用来设置 SIGINT
(由 Ctrl+C 触发)的处理函数为 handle_sigint
。这意味着当用户按下 Ctrl+C 时,不会像通常那样终止程序,而是调用 handle_sigint
函数。函数接收一个整型参数 signum
,它是被捕获的信号的编号。
程序将进入一个无限循环,每秒输出 "Program running... "这个提示词,并通过 sleep(1)
暂停一秒。在这期间,如果程序接收到信号,将执行相应的处理函数。
注意
不过在多线程环境中使用 signal
可能会有问题,另外 signal
函数有可能会有可移植性问题,所以可以考虑使用 sigaction
来增加兼容性。