如何在SIGINT处理程序中清除本地数据 [英] How to clean up local data in SIGINT handler

查看:174
本文介绍了如何在SIGINT处理程序中清除本地数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在SIGINT处理程序中执行清理功能,但无法将本地数据传递给它.这里是一个例子:

I need to execute clean up functions in SIGINT handler, but I can't pass local data to it. Here an example:

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);
}

如何实现这种行为?我试过使这个变量是全局的,但是 我无法在编译时调用此函数(错误:initializer元素不是编译时常量).

How can I implement such behaviour? I've tried make this variables are global, but I can't invoke this functions at compile time (error: initializer element is not a compile-time constant).

推荐答案

只能保证非常有限数量的函数是异步信号安全的,因此可以从信号处理程序exit() f.e中调用.不属于他们.

Only a very limited number of functions is guaranteed to be async-signal-safe and therefore may be called from within a signal handler, exit() f.e. does not belong to them.

采用其他方法:

#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. */
}

有关更多信息,请参见

注意:要最大程度地便携,您想使用sigaction()而不是signal().

Note: To be maximal portable you want to use sigaction() instead of signal().

替换signal()的代码可能如下所示:

The code to replace signal() might look like this:

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

这篇关于如何在SIGINT处理程序中清除本地数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆