Linux进程守护C++实现

xingyun86 2021-9-28 1921

Linux进程守护C++实现

Linux进程守护使用脚本也很容易实现,但是有时需要各种自定义的需求做一个代码级的也是不错。

#ifndef _MSC_VER
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <dirent.h>
#include <ctype.h>
#include <syslog.h>
#include <termios.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
static bool flag = true;
void create_daemon();
void handler(int);
#define SELFNAME "appdogd" //守护线程名称
#define APPNAME  "testuidemo" //需要启动检测的程序
#define RUNNAME  "/home/pi/testuidemo&" //程序目录和资源
//判断进程是否存在 预先判断守护进程是否存在,若已存在,不生成守护进程,若不存在,生成守护进程,在判断程序是否运行
int judge_pid_exist(const char* pidName) //判断进程是否运行
{
    int cnt = 0;
    DIR* dir = NULL; //进程目录
    struct dirent* next = NULL;
    FILE* status = NULL;
    char buffer[1024] = { 0 };
    char name[1024] = { 0 };
    dir = opendir("/proc"); ///proc中包括当前的进程信息,读取该目录
    if (dir == NULL) //目录不存在结束
    {
        printf("Cannot open /proc\n");
        return (-1);
    }
    //遍历 读取进程信息
    while ((next = readdir(dir)) != NULL)
    {
        //跳过"."和".."两个文件名
        if ((strcmp(next->d_name, "..") == 0) || (strcmp(next->d_name, ".") == 0))
        {
            continue;
        }
        //如果文件名不是数字则跳过
        if (isdigit(*next->d_name) == 0)
        {
            continue;
        }
        //判断是否能打开状态文件
        sprintf(buffer, "/proc/%s/status", next->d_name);
        if ((status = fopen(buffer, "r")) != NULL)
        {
            //读取状态文件
            if (fgets(buffer, sizeof(buffer) / sizeof(*buffer), status) == NULL)
            {
                fclose(status);
                continue;
            }
            fclose(status);
            sscanf(buffer, "%*s %s", name); //读取PID对应的程序名,格式为Name:  程序名
            if (strstr(name, pidName) != NULL)
            {
                cnt++;//符合
            }
        }
    }
    closedir(dir);
    return cnt;
}
void init_daemon(void)  //守护进程初始化函数
{
    int pid = 0;
    int i = 0;
    if (pid = fork())
    {
        exit(0);//是父进程,结束父进程
    }
    else if (pid < 0)
    {
        exit(1);//fork失败,退出
    }
    setsid(); //第一子进程成为新的会话组长和进程组长,并与控制终端分离
    for (i = 0; i < NOFILE; i++)
    {
        close(i);//关闭打开的文件描述符
    }
    chdir(".");//改变工作目录到/tmp
    umask(0);//重设文件创建掩模
    while (1) //判断程序是否运行
    {
        if (judge_pid_exist(APPNAME) == 0)
        {
            system(RUNNAME);//father
        }
        sleep(3);
    }
}
#endif // !_MSC_VER
int main(int argc, char ** argv)
{
	std::cout << "Hello CMake." << std::endl;
    if (judge_pid_exist(SELFNAME) == 0)
    {
        init_daemon(); //判断守护进程是否已运行
    }
    return 0;
}


×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回