征集,进程意外终止后,自动重启的方法

dongjiawei316 2009-10-13 10:16:18
我有一个程序,要求能够一直运行,故要求在其意外终止后,自动重启。
请问大家,这有些什么样的方法呢?如果有例程就更感谢了。
...全文
742 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
dongjiawei316 2009-10-14
  • 打赏
  • 举报
回复
对脚本不太了解,他一定很可靠吗?
目前我用如下方法实现了,

[Quote=引用 19 楼 mymtom 的回复:]
2.
C/C++ code pid_t pid;int status;for (;;) {
pid= fork();if (pid<0) {
exit(1);
}elseif (pid==0) {
execlp("YourProgram","YourProgram", (char*)0);
}else {
waitpid(pid,&status,0);
}
}
[/Quote]
但是我在
C/C++ code
waitpid(pid,&status,0);
sleep(10);
才能成功重启。
mymtom 2009-10-14
  • 打赏
  • 举报
回复
上面笔误。
1.
while [ 0 ]; do
YourProgram &
wait $!
done


2.
    pid_t pid;
int status;

for (;;) {
pid = fork();
if (pid < 0) {
exit(1);
} else if (pid == 0) {
execlp("YourProgram", "YourProgram", (char *)0);
} else {
waitpid(pid, &status, 0);
}
}
mymtom 2009-10-14
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 xyrbj 的回复:]
引用 15 楼 dongjiawei316 的回复:
谢谢十楼提供的源代码!我试试看


不客气 你试试看。这个东西比较简单 用shell 足以完成了。呵呵


如果没有跑通的话。我把我之前工作中用到的守护脚本 发给你参考
[/Quote]
这个脚本太烂了吧,
考虑一下,我正在看这个进程的log通常用 view YourProgram.log
这个脚本会出错的。
可靠的办法是
1.
while [ 0 ]; do
YourProgram.pid &
wait $!
done


2.

pid_t pid;
int status;

for (;;) {
pid = fork();
if (pid < 0) {
exit(1);
} else if (pid == 0) {
execlp("YourProgram", "YourProgram", (char *)0);
} else {
waitpid(pid, &status, 0);
}
}
dongjiawei316 2009-10-13
  • 打赏
  • 举报
回复
kill指kill函数,它可以通过pid检测一个进程是否存在。
[Quote=引用 6 楼 wlabing 的回复:]
你可以使用ps定时的查询。
“kill的话,程序中也不知道要监控的进程的PID啊!”不明白你说的是什么意思。监控进程名,而不监控它的PID。

还有一种方法,把程序添加到inittab中,其中action项指定为respawn。
[/Quote]
回复2楼,atexit由exit调用,当意外终止时,不会调用atexit函数的
不动如岳 2009-10-13
  • 打赏
  • 举报
回复
只知道做个脚本监控
wlabing 2009-10-13
  • 打赏
  • 举报
回复
你可以使用ps定时的查询。
“kill的话,程序中也不知道要监控的进程的PID啊!”不明白你说的是什么意思。监控进程名,而不监控它的PID。

还有一种方法,把程序添加到inittab中,其中action项指定为respawn。
dongjiawei316 2009-10-13
  • 打赏
  • 举报
回复
但如何监控另一个进程是否存在呢?难道用ps不断查询吗?kill的话,程序中也不知道要监控的进程的PID啊!
darkone 2009-10-13
  • 打赏
  • 举报
回复
或写个corntab脚本监控
darkone 2009-10-13
  • 打赏
  • 举报
回复
守护进程,一直监控应用运行状态,挂了就重启。。。
XyRbj 2009-10-13
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 dongjiawei316 的回复:]
谢谢十楼提供的源代码!我试试看
[/Quote]

不客气 你试试看。这个东西比较简单 用shell 足以完成了。呵呵


如果没有跑通的话。我把我之前工作中用到的守护脚本 发给你参考
steptodream 2009-10-13
  • 打赏
  • 举报
回复
写个监控程序 如果挂了就启动
wlabing 2009-10-13
  • 打赏
  • 举报
回复
1.程序中使用atexit注册一个函数(该函数始终都会被调用),可以使用这个点完成自动重启。
2.使用一个监控进程,发现被监控的进程终止后再启动它,但如果监控进程终止掉就有问题了。
wlabing 2009-10-13
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 dongjiawei316 的回复:]
谢谢十楼提供的源代码!我试试看
我尝试了inittab的方法,目前存在两个问题:
1、init间隔的时间过长,我刚刚测试过程序终止1分钟及以上时间后,init才发现。不知这个时间是否可设。
2、我的程序用到自己的一个动态链接库,通过init启动程序时,该库找不到。

[/Quote]
1.间隔时间过长可能是你系统过于繁忙。至于是否有时间间隔参数不太清楚,个人认为当init收到它监控的进程退出信号后会立即fork一个子进程,然后exec调用,终止至重启的时间间隔主要花在fork和exec上,如果系统过于繁忙,那么时间间隔就会比较长。尝试:以较小的系统开销运行测试试一下。(我自己尝试过,只要进程一终止,init进程就立即重启一个进程,时间很短,大概1秒以内)

2.动态链接库找不到,很可能是你没有把自己的动态链接库放到系统默认的链接库目录,而是使用了如LD_LIBRARY_PATH等环境变量指定了目录,如果是这样,inittab中指定的程序执行时而该环境变量还未生效就找不到动态链接库。解决方法:把自己的动态链接库放到系统默认的动态链接库目录去或创建软链接。

如果这种方法不好用就自己编写一个脚本或程序进程监控吧。
dongjiawei316 2009-10-13
  • 打赏
  • 举报
回复
谢谢十楼提供的源代码!我试试看
我尝试了inittab的方法,目前存在两个问题:
1、init间隔的时间过长,我刚刚测试过程序终止1分钟及以上时间后,init才发现。不知这个时间是否可设。
2、我的程序用到自己的一个动态链接库,通过init启动程序时,该库找不到。
[Quote=引用 13 楼 wlabing 的回复:]
引用 8 楼 dongjiawei316 的回复:
kill指kill函数,它可以通过pid检测一个进程是否存在。
引用 6 楼 wlabing 的回复:
你可以使用ps定时的查询。
  “kill的话,程序中也不知道要监控的进程的PID啊!”不明白你说的是什么意思。监控进程名,而不监控它的PID。

  还有一种方法,把程序添加到inittab中,其中action项指定为respawn。

回复2楼,atexit由exit调用,当意外终止时,不会调用atexit函数的


嗯,确实如此...
那可以使用监控进程或添加到/etc/inittab文件的方法。id:runlevel:action:程序
“kill指kill函数,它可以通过pid检测一个进程是否存在。”kill函数是向指定的进程发送指定信号的函数,为何要用kill函数来检测?
[/Quote]
lidowx 2009-10-13
  • 打赏
  • 举报
回复
做个守护进程
wlabing 2009-10-13
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 dongjiawei316 的回复:]
kill指kill函数,它可以通过pid检测一个进程是否存在。
引用 6 楼 wlabing 的回复:
你可以使用ps定时的查询。
“kill的话,程序中也不知道要监控的进程的PID啊!”不明白你说的是什么意思。监控进程名,而不监控它的PID。

还有一种方法,把程序添加到inittab中,其中action项指定为respawn。

回复2楼,atexit由exit调用,当意外终止时,不会调用atexit函数的
[/Quote]

嗯,确实如此...
那可以使用监控进程或添加到/etc/inittab文件的方法。id:runlevel:action:程序
“kill指kill函数,它可以通过pid检测一个进程是否存在。”kill函数是向指定的进程发送指定信号的函数,为何要用kill函数来检测?
yueyinggufan 2009-10-13
  • 打赏
  • 举报
回复
1 corntab

2 父子进程。
父进程循环等待子进程结束,结束了再启子进程
子进程用exec函数调用你那个程序

3 atexit函数 有一定局限性 看了atexit函数的要求你就知道了
XyRbj 2009-10-13
  • 打赏
  • 举报
回复
###监护进程休眠时间
SLEEPTIME=1;
还有就是这个 设置成你需要 循环检测的时间。


别忘了 启动脚本 nohup AutoCheck_ >> ./AutoCheck_.log &

把日志保留下来这样好看什么时候掉的。
XyRbj 2009-10-13
  • 打赏
  • 举报
回复
写一个shell就行了!当然这个程序要增加自我进程检测函数判别不能启动1个以上的程序。我写的这个脚本也有自检功能。
我给你写了一个,能跑通的测试过的 你把YourProgram 这里替换成你程序的名字就行了。

#!/dev/sh -x

#RUN_HOME=/Manuel.d/bin
RUN_HOME=/root/bin
###停滞状态
STOP=0;
###监护进程休眠时间
SLEEPTIME=1;
###是否开启AutoCheck监护脚本 1开0关
CHECKSWICH=1;
#CHECKSWICH=0;
###是否开启自我检查脚本 1开0关
SELFCHECKSWICH=1;
#SELFCHECKSWICH=0;
###脚本连接个数2-1
CONNENTCOUNT=2;

CheckProg()
{
while [ ${CHECKSWICH} ]
do

Date=` date +'%Y-%m-%d/%H:%M:%S' `;
echo "在"$Date"时间段进行:YourProgram进程监护";

ps -ef | grep -v grep | grep "YourProgram" |wc|awk '{print $1}'|read state;

if [ ${state} -eq ${STOP} ]
then

echo "YourProgram 进程异常停止\n";
##########################
##在这里加上启动程序的命令
##########################

fi
echo "YourProgram 进程已被激活\n";
echo "PS:下一次检测时间在"$SLEEPTIME"秒后\n";
sleep ${SLEEPTIME};
done
}

SelfCheck()
{
if [ ${SELFCHECKSWICH} ]
then
sleep 3;
ps -ef | grep -v "grep" | grep "AutoCheck_" | wc |awk '{print $1}'|read count;

if [ ${count} -ge ${CONNENTCOUNT} ]
then

echo "启动失败,此进程现已存在.当前进程存在个数${count}\n"
exit;
fi
echo "准备启动自动监护过程.\n"
fi
}

Main()
{
SelfCheck;
CheckProg;
}

if [ $# -ne 1 ] || [ $1 != 1 ]
then
exit;
fi

if [ $1 = 1 ]
then
Main;
fi

exit;
challenge99 2009-10-13
  • 打赏
  • 举报
回复
在父进程里面等信号.....

23,110

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧