如何在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