可以分三步来做:
做两个简单的守护进程,并能正常运行
监控进程是否在运行
启动进程
综合起来就可以了,代码如下:
被监控进程thisisatest.c(来自http://www.cnblogs.com/ringwang/p/3528093.html):
#include
#include
#include
#include
#include
#include
#include
#include
void init_daemon()
{
int pid;
int i;
pid=fork();
if(pid<0)
exit(1); //创建错误,退出
else if(pid>0) //父进程退出
exit(0);
setsid(); //使子进程成为组长
pid=fork();
if(pid>0)
exit(0); //再次退出,使进程不是组长,这样进程就不会打开控制终端
else if(pid<0)
exit(1);
//关闭进程打开的文件句柄
for(i=0;i close(i); chdir("/root/test"); //改变目录 umask(0);//重设文件创建的掩码 return; } void main() { FILE *fp; time_t t; init_daemon(); while(1) { sleep(60); //等待一分钟再写入 fp=fopen("testfork2.log","a"); if(fp>=0) { time(&t); fprintf(fp,"current time is:%s\n",asctime(localtime(&t))); //转换为本地时间输出 fclose(fp); } } return; } 监控进程monitor.c: #include #include #include #include #include #include #include #include #include #include #include #define BUFSZ 150 void init_daemon() { int pid; int i; pid=fork(); if(pid<0) exit(1); //创建错误,退出 else if(pid>0) //父进程退出 exit(0); setsid(); //使子进程成为组长 pid=fork(); if(pid>0) exit(0); //再次退出,使进程不是组长,这样进程就不会打开控制终端 else if(pid<0) exit(1); //关闭进程打开的文件句柄 for(i=0;i close(i); chdir("/root/test"); //改变目录 umask(0);//重设文件创建的掩码 return; } void err_quit(char *msg) { perror(msg); exit(EXIT_FAILURE); } // 判断程序是否在运行 int does_service_work() { FILE* fp; int count; char buf[BUFSZ]; char command[150]; sprintf(command, "ps -ef | grep thisisatest | grep -v grep | wc -l" ); if((fp = popen(command,"r")) == NULL) err_quit("popen"); if( (fgets(buf,BUFSZ,fp))!= NULL ) { count = atoi(buf); } pclose(fp); return count; // exit(EXIT_SUCCESS); } void main() { FILE *fp; time_t t; int count; init_daemon(); while(1) { sleep(10); //等待一分钟再写入 fp=fopen("testfork3.log","a"); if(fp>=0) { count = does_service_work(); time(&t); if(count>0) fprintf(fp,"current time is:%s and the process exists, the count is %d\n",asctime(localtime(&t)), count); //转换为本地时间输出 else { fprintf(fp,"current time is:%s and the process does not exist, restart it!\n",asctime(localtime(&t))); //转换为本地时间输出 system("/home/user/daemon/thisisatest"); //启动服务 } fclose(fp); } } return; } 具体CMD命令: cc thisisatest.c -o thisisatest ./thisisatest cc monitor.c -o monitor ./monitor tail -f testfork3.log -- 查看日志
这跟execvp函数的实现方式有关:
int execvp(const char *file ,char * const argv []);
execvp()会从PATH 环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个参数argv传给该欲执行的文件。如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno中。
之所以显示“fail to exec”,是因为在PATH环境变量所指的目录中没有名为“hello”的程序。建议进行如下操作:
1、运行“echo $PATH”,查看一下PATH环境变量指向那些目录
2、编写一个输出“hello world”的程序,并命名为hello,即执行命令:
gcc -o hello hello.c
3、把名为”hello“的程序拷贝到PATH变量所指的其中一个目录中