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

Terminating a program with calling atexit functions (Linux)

本文关键字:一个 Linux 程序 终止 调用 atexit 函数      更新时间:2023-10-16

是否有一种方法可以向进程(在Linux中)发送信号,从而在经过" atexit-function "后导致进程终止?(在这种情况下: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");
}

atexit的手册页:

使用atexit()(和on_exit(3))注册的函数不会被调用如果进程异常终止,因为一个信号。

atexit在主例程返回或调用exit时调用,而不是在信号时调用。

当你呼叫pkill时,你正在发送SIGTERM信号。用signalsigaction来处理这个信号(在SIGTERM, SIGINT, SIGFPE,…上定义处理程序),在退出程序之前停止引擎。

示例摘自GNU C库文档:

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"信号",它告诉操作系统将您的进程从活动进程列表中删除,而无需进一步通知!)

相关文章: