linux下经常要监视一个进程的运行,如果这个进程由于各种原因崩溃或退出了需要让监视它的程序重新把它运行起来,下面给出一种实现方法:
1.首先要保证一个程序只有一个实例在运行,避免重复启动:
在程序的main函数入口处先获取自身的PID保存在一个指定的文件中,之后程序在运行的时候我们就可以从这个文件中取出PID来判断程序是否在运行了。实际代码中main()函数里面前两行是:
CheckPID();
SavePID();
具体实现:
#define PID_PATH "/myproc.pid"
void CheckPID()
{
int pid;
char str[256] = {0};
FILE *fp = fopen(PID_PATH, "r");
if (fp)
{
fgets(str, sizeof(str), fp);
pid = atoi(str);
fclose(fp);
if (pid > 0 && (!kill(pid, 0)))
{
printf("当前进程正在运行,请先停止.\n");
exit(-1);
}
}
}
void SavePID()
{
FILE *fp = fopen(PID_PATH, "w");
if (fp)
{
fprintf(fp, "%d", getpid());
fclose(fp);
}
}
2.在监视进程中读取对方进程保存的PID,拿到这个PID之后,遍历/proc目录下的所有PID与之进行对比,如果相等说明进程正在运行,否则重新启动这个进程:
static int check_digit(const char *str)
{
int len , i;
len = strlen(str);
if (len <= 0)
{
return -1;
}
for (i=0; i<len; i++)
{
if (str[i] < '0' || str[i] > '9')
{
return -1;
}
}
return 0;
}
int check_proc(pid_t pid)
{
DIR *dp;
char dir[] = "/proc";
struct dirent *dirp;
chdir(dir);
if ((dp = opendir(dir)) == NULL)
{
return -1;
}
while ((dirp = readdir(dp)) != NULL)
{
char data[32] = {0};
sprintf(data, "%s", dirp->d_name);
if (check_digit(data))
{
continue;
}
if ((atoi(data) == pid))
{
return 0;
}
}
return -1;
}
void WatchProc()
{
int pid;
char str[32] = {0};
char cmdstring[] = "/test"; // 需要监视的进程
FILE *fp = fopen(PID_PATH , "r");
if (fp)
{
fgets(str, sizeof(str), fp);
fclose(fp);
if (strlen(str) > 0)
{
pid = atoi(str);
if (check_proc(pid))
{
system( cmdstring );
}
}
}
}