Linux下通过daemon守护进程,实现服务进程crash自动重启
参考:Linux下实现通过一个进程控制另一个进程的启动、停止、崩溃重启有时候我们希望部署一些服务,而这些服务可能会在某种原因下崩溃,可能是bug或者其他原因,这个时候为了能继续维持服务,就将该服务进程挂在另一个进程下。这里的daemon守护进程并非后台程序,可以通过其他操作使其进入后台如nohup或者将代码改成真正的daemon后台守护进程。
·
参考:Linux下实现通过一个进程控制另一个进程的启动、停止、崩溃重启
有时候我们希望部署一些服务,而这些服务可能会在某种原因下崩溃,可能是bug或者其他原因,这个时候为了能继续维持服务,就将该服务进程挂在另一个进程下,达到自动重启的目的。这里的daemon守护进程不是后台程序,可以通过其他操作使其进入后台如nohup或者可以将代码改成真正的daemon后台守护进程。
使用gcc编译并运行
gcc -o daemon daemon.c -pthread
gcc -o test_app test.c
./daemon test_app
#可以加参数,不过在解析参数时有一点区别
#example: ./daemon test_app 192.168.0.2
可以使用systemd让程序成为系统服务,参考How to restart a process automatically when it killed in linux/CentOS,或者开机自启:
vim /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will exit 0 on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
/bin/bash test_app.sh
exit 0
test_app.sh(注意需要使其有可执行权限chmod +x test_app.sh):
#!/bin/sh
cd /folder_to_app
./daemon test_app &
源代码如下(思考:如何做成免杀程序呢?):
//daemon.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <pthread.h>
char glb_process[1024] = "";
char glb_arg[1024] = "";
int glb_pid = -1;
int create_process(const char* cmd, const char* arg)
{
int pid = fork();
if(pid == -1)
{
printf("fork error\n");
return -1;
}else if(pid == 0){
int ret = execl(cmd, arg, NULL);
if(ret < 0)
{
printf("execl : %s(%d)\n", strerror(errno), errno);
return -2;
}
}
return pid;
}
int kill_process(int pid)
{
int ret = kill(pid, SIGKILL);
if(ret < 0)
{
printf("kill : %s(%d)\n", strerror(errno), errno);
return -1;
}
return 0;
}
int judge_proc_exist(int pid)
{
DIR* dir;
struct dirent* s_dir;
struct stat file_stat;
const char *proc_dir = "/proc/";
char s_pid[10] = "";
if((dir = opendir(proc_dir)) == NULL)
{
printf("open %s error : %s(%d)", proc_dir, strerror(errno), errno);
return 1;
}
sprintf(s_pid, "%d", pid);
int found = 0;
while((s_dir = readdir(dir)) != NULL)
{
lstat(s_dir->d_name, &file_stat);
if((!strcmp(s_pid, s_dir->d_name)) && (S_ISDIR(file_stat.st_mode))){
found = 1;
break;
}
}
closedir(dir);
return found;
}
void* entry_thread(void* user_data)
{
glb_pid = create_process(glb_process, glb_arg);
printf("Process(%d) start...\n", glb_pid);
return 0;
}
void sig_child(int signo)
{
pid_t pid;
int stat;
pid = wait(&stat);
printf( "Process %d exit\n", pid );
glb_pid = create_process(glb_process, glb_arg);
printf( "Restart %d \n", glb_pid );
return;
}
int main(int argc, char* argv[])
{
pthread_t it;
if(argc < 2)
{
printf("Usage : %s exe path [arg]\n", argv[0]);
printf("build at %s %s\n", __DATE__, __TIME__);
return -1;
}
if(argc > 1)
{
strcpy(glb_process, argv[1]);
}
if(argc > 2)
{
strcpy(glb_arg, argv[2]);
}
signal(SIGCHLD, &sig_child);
pthread_create(&it, NULL, entry_thread, NULL );
while(1)
{
usleep(20*1000);
}
}
测试程序
//test.c
#include <stdio.h>
#include <unistd.h>
int main(void)
{
while(1)
{
printf("Hello World!\n");
usleep(1000*1000);
}
return 0;
}
更多推荐
已为社区贡献2条内容
所有评论(0)