繁体   English   中英

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

[英]Are atexit() registered handlers called just one time?

我有一个用atexit()注册的 function 程序:

atexit(exitFunc);

像这样的信号处理程序:

void sigHandler(int sigNo)
{
  switch (sigNo)
  {
  case SIGINT:
  case SIGTERM:
  case SIGHUP:
    exit(0);
    break;
  }
}

我已经检查过,第一次向进程发送 SIGINT 时,执行exit(0)时会调用exitFunc() 但是,如果进程仍在运行( exitFunc()需要一段时间)并且我再次发送 SIGNIT,则当exit(0)立即终止进程时,不会再次调用exitFunc()

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

(我查看了atexit文档,但具体点尚不清楚)

man 3 atexit看来,用atexit注册的函数只被调用一次

同一个 function 可能会被注册多次:每次注册都会调用一次。

如果您希望 function 被多次调用,您应该在需要时/如果需要多次重新注册它。 但是,请小心,因为您要完成的工作具有非常可疑的效用。 如果您正在做的任何事情都需要在调用exit()后使用atexit重新注册相同的 function,那么您可能需要考虑其他方法。

在您的示例中,由于sigHandler()是一个信号处理程序,因此您受到限制并且只能调用异步信号安全函数,请参阅man 7 signal safety以获取列表。 请注意, exit()不在其中,因此从sigHandler()调用exit() ) 是未定义的行为。 无论规范说什么,你都在破坏它。 您可以使用_exit() (注意前导下划线)安全地退出信号处理程序的唯一方法,它会直接退出而不进行任何清理。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM