Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C atexit()注册的处理程序是否只调用一次?_C - Fatal编程技术网

C atexit()注册的处理程序是否只调用一次?

C atexit()注册的处理程序是否只调用一次?,c,C,我有一个程序,其函数注册为atexit(): 还有这样一个信号处理器: void sigHandler(int sigNo) { switch (sigNo) { case SIGINT: case SIGTERM: case SIGHUP: exit(0); break; } } 我已经检查了第一次向进程发送SIGINT时,在执行exit(0)时调用exitFunc()。但是,如果进程仍在运行(exitFunc()make-take-time),并且我

我有一个程序,其函数注册为
atexit()

还有这样一个信号处理器:

void sigHandler(int sigNo)
{
  switch (sigNo)
  {
  case SIGINT:
  case SIGTERM:
  case SIGHUP:
    exit(0);
    break;
  }
}
我已经检查了第一次向进程发送SIGINT时,在执行
exit(0)
时调用
exitFunc()
。但是,如果进程仍在运行(
exitFunc()
make-take-time),并且我再次发送SIGNIT,则当
exit(0)
立即终止进程时,
exitFunc()
不会再次调用

这是正常的行为吗?使用
atexit()
注册的函数只调用一次?如果我希望下次到达
exit(0)
时调用它,我是否应该再次注册
exitFunc()

(我查看了文档,但具体的一点并不清楚)

从中可以清楚看出,在
atexit
注册的函数只调用一次:

同一函数可以注册多次:每次注册调用一次

如果希望多次调用该函数,则应在需要时重新注册多次。但是,要小心,因为您试图完成的工作具有非常可疑的实用性。如果在调用
exit()
后,您所做的任何操作都需要在
atexit
中重新注册相同的函数,那么您可能需要考虑其他方法

在您的示例中,由于
sigHandler()
是一个信号处理程序,因此您受到限制,只能调用异步信号安全函数,有关列表,请参阅。请注意,
exit()
不在其中,因此从
sigHandler()
调用
exit()
是未定义的行为。不管说明书上说什么,你都在破坏它。安全地从信号处理程序退出的唯一方法是使用(请注意前导下划线),它不进行任何清理即可直接退出


如果需要执行清理,但仍希望退出信号处理程序,则在信号处理程序本身中执行清理,并在完成后调用
\u exit()
。如果需要非异步信号安全函数来执行清理,请使用信号处理程序简单地设置一个全局变量,然后在主程序中需要时检查它:如果设置了,则执行清理并退出(现在可以使用
exit()
)。

函数
exit
不是异步信号安全的,因此不应该从信号处理程序调用它。请参阅“我建议修改信号处理程序中类型为
volatile sig_atomic_t
的变量”中的表格,在主处理中检查此变量,并在变量值指示时调用
exit
。要回答“这是正常行为吗?使用atexit()注册的函数只调用一次?”是的。
exit
手册页面似乎表明
POSIX.1
声明多次调用
exit
是未定义的行为。在查看注释后,我编辑了我的问题,删除了“这是正常行为吗?”因为这可能会令人困惑。
void sigHandler(int sigNo)
{
  switch (sigNo)
  {
  case SIGINT:
  case SIGTERM:
  case SIGHUP:
    exit(0);
    break;
  }
}