优雅地退出C应用程序

时间:2012-08-11 13:53:59

标签: c shell

我目前有一个用C语言编写的程序,它有一个处理信息的无限循环,每个循环大约需要5分钟才能完成。我想在shell脚本中具有以下功能:

  • 终止C程序
  • 制作来源
  • 运行程序

问题是,我不知道如何告诉我的C程序退出而不执行ctrl + c这样的操作,我宁愿它在终止自身之前完成处理它当前正在处理的信息。

3 个答案:

答案 0 :(得分:4)

告诉流程完成业务并彻底退出的POSIX标准方法是向其发送SIGTERM信号。根据您的应用程序,它可能或不适合退出SIGINT,这意味着中断进程,而不是终止进程。 (Control-c发送SIGINT。)

尝试在紧密的循环中放置一个标志;在退出很容易的时候检查标志,但仍然经常足以立即退出。在您的情况下,收到SIGTERM可能会立即在系统日志中显示一条消息,然后承诺在接下来的5分钟内退出。

您的信号处理程序将如下所示:

static int signalled;  // if nonzero, what signal have we been sent?

static void SignalHandler(int signum) {
  signalled = signum;
}

在每次I / O操作后检查全局static变量signalled,这意味着每秒多次。

这是我捕获和恢复信号的代码:

static __sighandler_t sh, si, st;

static void catch_signals(void) {
  if ((sh = signal(SIGHUP, SignalHandler)) == SIG_IGN) signal(SIGHUP, SIG_IGN);
  if ((si = signal(SIGINT, SignalHandler)) == SIG_IGN) signal(SIGINT, SIG_IGN);
  if ((st = signal(SIGTERM, SignalHandler)) == SIG_IGN) signal(SIGTERM, SIG_IGN);
  signalled = 0;
}

static void restore_signals(void) {
  signal(SIGHUP, sh);
  signal(SIGINT, si);
  signal(SIGTERM, st);
}

(这段代码来自一个图书馆,所以我要特别注意留下我发现它们的方式。)

奖励技巧:当时间到期时(这是一个电视录制库),计时器只设置signalled = SIGTERM,并使用相同的逻辑正常退出录像机。

答案 1 :(得分:3)

  像ctrl + c一样,我宁愿它完成处理它的信息   目前正在努力终止itsel

为SIGINT或任何你想要的东西建立一个信号处理程序,并在收到它后进行清理。 不应该在处理程序本身进行清理

volatile sig_atomic_t do_cleanup = 0;
void handler(int sig)
{
    do_cleanup = 1;
}

然后在您的主循环中,您只需要测试do_cleanup并在您需要时退出。如果您还没有这样做,还必须小心处理EINTR错误。

答案 2 :(得分:1)

以下是如何从shell发送信号:

http://bash.cyberciti.biz/guide/Sending_signal_to_Processes

或只是man kill

以下是对信号的反应:

http://www.cs.cf.ac.uk/Dave/C/node24.html#SECTION002400000000000000000