如何在SIGINT处理程序中清理本地数据
我需要在SIGINT处理程序中执行清理函数,但我无法将本地数据传递给它。 这是一个例子:
int main(int argc, char *argv[]) { struct database *db = db_cursor(); sockfd_t master_socket = init_server(); signal(SIGINT, sigint_handler); while (1) { // accepting connections } } void sigint_handler(int s) { destroy_db(db); shutdown(master_socket, SHUT_RDWR); close(master_socket); exit(EXIT_SUCCESS); }
我该如何实现这种行为? 我试过让这个变量是全局的,但我不能在编译时调用这个函数(错误:初始化元素不是编译时常量)。
只保证非常有限数量的函数是异步信号安全的,因此可以从信号处理程序中调用, exit()
fe不属于它们。
采取不同的方法:
#include volatile sig_atomic_t sigint_received = 0; /* volatile might be necessary depending on the system/implementation in use. (see "C11 draft standard n1570: 5.1.2.3")*/ void sigint_handler(int s) { sigint_received = 1; } int main(void) { signal(SIGINT, sigint_handler); while (!sigint_received) { /* Do stuff. */ } /* Clean up here. */ }
有关详细信息,请参阅
- Linux man-page here
man 7 signal
- POSIX规范在这里。
注意:要获得最大的可移植性,您需要使用sigaction()
而不是signal()
。
替换signal()
的代码可能如下所示:
struct sigaction sa = { sigint_handler /*, SA_RESTART */ /* Set this by if blocking calls like read() or accept() should _not_ return on signal reception. */ }; if (-1 == sigaction(SIGINT, &sa, NULL)) { perror("sigaction() failed"); exit(EXIT_FAILURE); }
关于sigaction()
文档:
- Linux的
- POSIX