在Linux下,通过在崩溃处理程序中捕获异常(例如在段错误上),程序在崩溃时重启自身的最佳方法是什么?
答案 0 :(得分:11)
最简单的是
while [ 1 ]; do ./program && break; done
基本上,你运行程序直到它返回0,然后你就会中断。
答案 1 :(得分:7)
SIGSEGV
可以被捕获(请参阅man 3 signal
或man 2 sigaction
),程序可以调用其中一个exec
函数系列,以便重新启动。同样适用于大多数运行时崩溃(SIGFPE
,SIGILL
,SIGBUS
,SIGSYS
,...)。
在任何情况下,如果在死亡之前有任何想要清理的资源,请确保不在SIGTERM
上自动重启,否则愤怒的用户将使用SIGKILL
你会留下一团糟。
答案 2 :(得分:6)
您可以拥有一个基本上fork()
的循环,完成孩子的实际工作,然后等待孩子并检查其在父母中的退出状态。您还可以使用以类似方式监视和重新启动程序的系统,例如daemontools,runit等。
答案 3 :(得分:3)
作为对此处提议内容的补充:
另一个选择就是为getty守护进程做的事情。请参阅/ etc / inittab和相应的inittab(5)手册页。它似乎是整个系统范围内的意思; - )。
它可能看起来像下面的文件片段。明显的优势这意味着非常标准,它允许通过运行级别控制您的守护进程。
# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
答案 4 :(得分:1)
进程无法自行重启,但您可以使用crontab(1)
之类的实用程序来安排脚本以定期检查进程是否仍处于活动状态。
答案 5 :(得分:1)
程序本身显然不应该检查它是否正在运行:)
对于给定的字符串,大多数企业解决方案实际上只是花费了ps()
的输出,并且在满足某些条件的情况下执行操作 - 即如果找不到您的进程,则调用启动脚本。
答案 6 :(得分:0)
如果特定于segfault,请尝试以下代码。这可以根据需要进行修改。
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <poll.h>
sigjmp_buf buf;
void handler(int sig) {
siglongjmp(buf, 1);
}
int main() {
//signal(SIGINT, handler);
//register all signals
struct sigaction new_action, old_action;
new_action.sa_handler = handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGSEGV, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGSEGV, &new_action, NULL);
if (!sigsetjmp(buf, 1)){
printf("starting\n");
//code or function/method here
}
else{
printf("restarting\n");
//code or function/method here
}
while(1) {
poll(NULL,0,100); //ideally use usleep or nanosleep. for now using poll() as a timer
printf("processing...\n");
}
return 0; //or exit(SUCESS)
}