【发布时间】:2016-06-04 14:04:37
【问题描述】:
我需要在 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);
}
如何实现这种行为?我试过让这个变量是全局的,但是 我无法在编译时调用此函数(错误:初始化元素不是编译时常量)。
【问题讨论】:
-
您不应该在处理程序本身中执行所有这些逻辑。只需让它设置一个标志,并在主循环中测试该标志。
-
加上 Oliver 的评论:输入标志
sig_atomic_t。 -
现在它可以工作了,但是我有像
accept这样的阻塞调用,当我调用SIGINT时它不会立即停止。我应该使用多路复用来解决这个问题吗? -
如果
accept()没有返回,请使用sigaction()而不是signal()创建此信号处理程序,并取消设置传递结构的成员SA_RESTART中的SA_RESTART标志。 -
您不需要在accept()上阻塞:只需将监听套接字设置为非阻塞,将其添加到select()ed(或polled)集合中,并在选择时检查标志() 返回 -1/EINTR。