如何清理 SIGINT 处理程序中的本地数据
How to clean up local data in SIGINT handler
我需要在 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()
f.e。不属于他们。
采取不同的方法:
#include <signal.h>
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 7 signal
- POSIX specifications here.
注意:为了最大限度地便携,您需要使用 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()
的文档:
我需要在 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()
f.e。不属于他们。
采取不同的方法:
#include <signal.h>
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 7 signal
- POSIX specifications here.
注意:为了最大限度地便携,您需要使用 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()
的文档: