1.缘起
这个系列会汇集一些临近deadline时的最后补救措施,以备不时之需。面临项目交付时,经常会有一些或大或小的功能项点,甚至是bug无法做完。这个时候,就需要一些终极补救措施来应对这种不时之需。
这里的第一个工具:
app_daemon,是针对那些需要长周期运行,但是因为一些内存泄露或者别的资源释放问题迟迟无法解决的情形,它叫应用程序看护工具,实际运行效果是这样的:
[root@localhost app_daemon]# ./app_daemon ./test_app
real app runing....
real app quited
Application scheduling exited. Restarting in 5 seconds...
real app runing....
real app quited
Application scheduling exited. Restarting in 5 seconds...
real app runing....
real app quited
Application scheduling exited. Restarting in 5 seconds...
即使在最终的产品中仍然需要这样的一个东西
它的源码参见后文,实际运行时的命令行参照下方的源码中的首行 usage。支持传参,最简单的圆用法上面对命令行加了黑体。
2.编码
//usage: app_daemon <app_to_daemon's cmd_line> [param1 param2 param3...]
//build:gcc app_daemon.c -o app_daemon
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void runWatchingAppAsSubApp(int argc, char *argv[]) {
char new_cmd[2048] = {0};
int i;
int l;
for(i=0; i<argc; ++i)
{
l = strnlen(new_cmd, 2048);
if(i==0){
continue; //i==0 is itsself
}
else{
snprintf(&new_cmd[l], sizeof(new_cmd)-l-1, "%s ", argv[i]);
}
// 替换为您的应用程序启动命令
system(new_cmd);
}
}
int main(int argc, char *argv[]) {
if(argc == 1)
{
printf("Usage:%s <app_to_watch> [param1, param2...]\n", argv[0]);
return 0;
}
while (1) {
pid_t pid = fork();
if (pid == 0) {
// 子进程中运行应用程序
runWatchingAppAsSubApp(argc, argv);
exit(0);
} else if (pid > 0) {
// 等待应用程序退出
int status;
waitpid(pid, &status, 0);
// 延时重启时间(单位:秒)
int restart_delay = 5; // 5 秒
printf("Application scheduling exited. Restarting in %d seconds...\n", restart_delay);
sleep(restart_delay);
} else {
printf("Fork failed\n");
return 1;
}
}
return 0;
}
附录A 用于测试的一个桩应用
void main(void)
{
printf("real app runing....\n");
sleep(3); //延时3秒
printf("real app quited\n");
}
~