How It Works
Toggle navigation
How It Works
Home
About Me
Archives
Tags
进程只有一个
2016-03-19 00:13:14
642
0
0
ochapman
#引 为了防止进程异常退出后服务停止,简单的做法,在crontab里定时检测(真有这么做的),若是进程不在就拉起。常见的问题有:检测进程是“存在”的,于是放弃拉起。或者进程是“不存在”的,于是不断地拉起。 很多情况下,程序需要限定有限(单个)进程运行,这个时候需要防止重复运行。 粗暴的做法,是通过ps命令然后grep等工具找到对应的进程名字是否进行判断。 这种方法的问题是,进程的名字并不是识别进程的标识。就好像,人的名字并不是真正地识别人一样(身份证号码)。无法保证其他程序名字和你写的不一样。 ![长相](https://mua.io/api/file/getImage?fileId=56ec2f6b2fa1ec184a7e51bc) 那么,能否在自己启动的时候判断是否还有一个另外的自己(进程) 假设能,那么判断期间内将有两个自己,因此跟命题要求不符(只能存在一个进程) ![进程只有一个](https://mua.io/api/file/getImage?fileId=56ec2c282fa1ec184a7e51bb) 简单地讲, > 不通过外界,你是无法确认是否自己是否还活着的。只能感觉自己将要死,但无法判断是否真的死了。 通过外界判断,需要遵守同样的规则。首先先看 #为什么需要pidfile 对于程序来讲,不通过外界,也无法判断自己是否还活着,常见的方法是通过pidfile。 在ubuntu上,由/sbin/start-stop-daemon来负责管理pidfile 如/etc/init.d/ntp start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS 其中,PIDFILE的值 PIDFILE=/var/run/ntpd.pid 文件内容是存放自己pid值,启动的时候, 如果存在pidfile文件,那么读取里面的pid值,并判断pid是否在运行着。 do_pidfile(const char *name) { FILE *f; static pid_t pid = 0; if (pid) return pid_check(pid); f = fopen(name, "r"); if (f) { enum status_code pid_status; if (fscanf(f, "%d", &pid) == 1) pid_status = pid_check(pid); else pid_status = status_unknown; fclose(f); if (pid_status == status_dead) return status_dead_pidfile; else return pid_status; } else if (errno == ENOENT) return status_dead; else fatal("unable to open pidfile %s", name); } 如果不存在这个文件,由启动脚本负责创建,并把目标进程的pid写到该文件上。 static void write_pidfile(const char *filename, pid_t pid) { FILE *fp; int fd; fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW, 0666); if (fd < 0) fp = NULL; else fp = fdopen(fd, "w"); if (fp == NULL) fatal("unable to open pidfile '%s' for writing", filename); fprintf(fp, "%d\n", pid); if (fclose(fp)) fatal("unable to close pidfile '%s'", filename); } 那么,如果判断pid是否存在着,先看上面的pid_check static enum status_code pid_check(pid_t pid) { if (execname && !pid_is_exec(pid, &exec_stat)) return status_dead; if (userspec && !pid_is_user(pid, user_id)) return status_dead; if (cmdname && !pid_is_cmd(pid, cmdname)) return status_dead; if (action != action_stop && !pid_is_running(pid)) return status_dead; pid_list_push(&found, pid); return status_ok; } 这里做了很多检查,主要跟start_stop_daemon的参数指定有关,重点是pid_is_running函数 #如何判断指定pid是否存在 方法很多,常见的有通过kill函数进行检测 ![kill](https://mua.io/api/file/getImage?fileId=56ecb3582fa1ec184a7e51bd) kill的原型是 int kill(pid_t pid, int sig) 说明 > If sig is 0, then no signal is sent, but error checking is still > performed; this can be used to check for the existence of a process ID > or process group ID kill返回0成功,-1失败,失败有3种情况,1. sig非法EINVAL。2. 没有权限EPERM。3.pid不存在ESRCH。 因此 kill(pid, 0) 返回0,或者-1且errno为EPERM,则说明pid存在;其他情况说明存在。 在上面的代码上pid_check正是使用了kill来检测 static bool pid_is_running(pid_t pid) { if (kill(pid, 0) == 0 || errno == EPERM) return true; else if (errno == ESRCH) return false; else fatal("error checking pid %u status", pid); } #pid不存在,但是pidfile存在? 显然,pidfile只是记录了目标进程的值,和pid是否还存在无关 如果直接kill掉pid,那么pidfile是有可能存在的。
Pre:
小试分答数据挖掘
Next:
pam简单例子
0
likes
642
Weibo
Wechat
Tencent Weibo
QQ Zone
RenRen
Table of content