我目前有一个程序,我用C编写了一个服务器,它有一个处理信息的无限循环,每个循环大约需要5分钟才能完成。我想有一个shell脚本以下功能:
正在退出C应用程序
- 终止的C程序
- 制作源
- 运行程序
的问题是,我不知道知道如何告诉我的C程序退出,而不需要按Ctrl + C之类的操作,我宁愿在终止它之前完成它正在处理的信息。
我目前有一个程序,我用C编写了一个服务器,它有一个处理信息的无限循环,每个循环大约需要5分钟才能完成。我想有一个shell脚本以下功能:
正在退出C应用程序
的问题是,我不知道知道如何告诉我的C程序退出,而不需要按Ctrl + C之类的操作,我宁愿在终止它之前完成它正在处理的信息。
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;
}
我检查全局变量static
每signalled
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
,并且相同的逻辑用于正常退出录音机。
如Ctrl + C,我宁愿它处理完它 目前正在终止itsel
前的信息来建立一个信号处理程序SIGINT或任何你想和后你做你清理收到它。 但是,您不应该在处理程序本身中进行清理。
volatile sig_atomic_t do_cleanup = 0;
void handler(int sig)
{
do_cleanup = 1;
}
然后在你的主循环,你只需要当你测试do_cleanup
和退出请。如果您尚未这样做,您还必须小心处理EINTR
错误。
这是不正确。该变量应该是易变的。 – 2012-08-11 14:06:15
@ JohannesSchaub-litb没错,我很sl。。 – cnicutar 2012-08-11 14:08:10
这里是如何从外壳发送信号:
http://bash.cyberciti.biz/guide/Sending_signal_to_Processes
或者干脆man kill
这里是如何对信号作出反应:
http://www.cs.cf.ac.uk/Dave/C/node24.html#SECTION002400000000000000000
@dear downvoter这是一个很好的答案。你能提供一个评论来证明弹性文字“这个答案没有用”吗? – cnicutar 2012-08-11 14:31:40