2012-08-11 98 views
1

我目前有一个程序,我用C编写了一个服务器,它有一个处理信息的无限循环,每个循环大约需要5分钟才能完成。我想有一个shell脚本以下功能:
正在退出C应用程序

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

的问题是,我不知道知道如何告诉我的C程序退出,而不需要按Ctrl + C之类的操作,我宁愿在终止它之前完成它正在处理的信息。

回答

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; 
} 

我检查全局变量staticsignalled I/O操作,这意味着每秒很多次。

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

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,并且相同的逻辑用于正常退出录音机。

+0

@dear downvoter这是一个很好的答案。你能提供一个评论来证明弹性文字“这个答案没有用”吗? – cnicutar 2012-08-11 14:31:40

3

如Ctrl + C,我宁愿它处理完它 目前正在终止itsel

前的信息来建立一个信号处理程序SIGINT或任何你想和后你做你清理收到它。 但是,您不应该在处理程序本身中进行清理。

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

然后在你的主循环,你只需要当你测试do_cleanup和退出请。如果您尚未这样做,您还必须小心处理EINTR错误。

+1

这是不正确。该变量应该是易变的。 – 2012-08-11 14:06:15

+0

@ JohannesSchaub-litb没错,我很sl。。 – cnicutar 2012-08-11 14:08:10