通过调用atexit函数终止程序(Linux)

时间:2016-10-28 19:24:17

标签: c++ linux signals

有没有办法向进程发送信号(在Linux中),这会导致在执行“atexit-functions”之后终止进程(在这种情况下:void shutdownEngines())?使用“pkill name”不起作用。

#include <cstdlib>
void shutdownEngines() {/*is not executed by "pkill name"*/}
int main() {
    atexit(shutdownEngines);
    while(true)
       doStuff();
}

用法:我正在编程一个机器人。每次我想测试它,我都会启动程序并用“pkill name”终止它,但是没有调用“shutdownEngines”并且机器人继续移动,从桌子上掉下来等。

我知道我可以做“pkill name; ./shutdownEngines.sh”,但在我的情况下这将是非常糟糕的风格(连接到引擎的gpio引脚的数量在主程序的头文件中定义(来源)主程序的代码不在机器人上,而是在我的计算机上。确保每个机器人上始终有一个“shutdownEngines.sh”程序/脚本和正确的引脚将非常复杂。

更新

以下代码完美无缺:

#include <iostream>
#include <csignal>
#include <cstdlib>
void signalHandler(__attribute__((unused)) const int signum) {
    exit(EXIT_FAILURE);
}
void driverEpilog() {
    std::cout << "shutting down engines...";
    //drv255(0,0);
}
int main() {
    signal(SIGTERM, signalHandler);
    atexit(driverEpilog);
    while(true)
        system("sleep 1");
}

1 个答案:

答案 0 :(得分:4)

来自atexit

的手册页
  

不调用使用atexit()(和on_exit(3))注册的函数          如果一个过程由于交付a而异常终止          信号。

当您的主例程返回或致电atexit时,

exit被调用,而不是在信号上。

当您致电pkill时,您正在发送SIGTERM信号。请使用signalsigaction处理此信号(在SIGTERM上定义处理程序,SIGINTSIGFPE,...)以在退出程序之前停止引擎

取自GNU C library documentation的示例:

void
termination_handler (int signum)
{
  struct temp_file *p;

  for (p = temp_file_list; p; p = p->next)
    unlink (p->name);  // don't delete files, stop your engines instead :)
}

int
main (void)
{
  …
  struct sigaction new_action, old_action;

  /* Set up the structure to specify the new action. */
  new_action.sa_handler = termination_handler;
  sigemptyset (&new_action.sa_mask);
  new_action.sa_flags = 0;

  sigaction (SIGINT, NULL, &old_action);
  if (old_action.sa_handler != SIG_IGN)
    sigaction (SIGINT, &new_action, NULL);
  sigaction (SIGHUP, NULL, &old_action);
  if (old_action.sa_handler != SIG_IGN)
    sigaction (SIGHUP, &new_action, NULL);
  sigaction (SIGTERM, NULL, &old_action);
  if (old_action.sa_handler != SIG_IGN)
    sigaction (SIGTERM, &new_action, NULL);
  …
}

(当然,没有处理程序可以处理SIGKILL&#34;信号&#34;,它告诉操作系统从活动进程列表中删除您的进程,恕不另行通知!)