如何让一个程序只有一个运行实例
需求
有的程序我们只希望它只有一个运行实例,也许你现在没有这个需求,说不定哪天就有了。
实现
本来是想通过一个文件来区别,比如进程起来的时候创建一个文件,结束的时候把文件删除,当新的进程起来的时候先判断这个文件是否存在,如果存在就退出;
这个解决方案的特点是简单,但是却有一个致命漏洞,如果这个进程运行的时候异常退出,或者用户在命令行通过kill -9 的方式杀掉的话,那么下次也将无法启动了。
下面是用文件锁的方式来实现:
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char **argv)
{
char *user=getenv("USER");
printf("the user is %s/n",user);
char *home=getenv("HOME");
if(!home){
home="/tmp/";
}
char *name=strcat(home,".mplayer_proc.pid");
printf("the name is %s/n",home);
int fd=open(name,O_RDWR|O_APPEND|O_CREAT,S_IRWXU);
if(fd <0){
perror("open error/n");
close(fd);
return -1;
}
int val;
if((val = fcntl(fd, F_GETFD, 0) <0 )) {
perror("fcntl");
close(fd);
return -1;
}
val |= FD_CLOEXEC;
if(fcntl(fd, F_SETFD, val) <0 ) {
perror("fcntl again");
close(fd);
return -1;
}
if(flock(fd,LOCK_EX|LOCK_NB)<0){
perror("flock error/n");
return -1;
}
sleep(10);
unlink(name);
return 0;
}
这样的话,可以保证在异常退出的时候能够正常运行,也能保证在一个实例运行的时候,另外一个不能运行;
问题
这种实现方式的问题在于,这个文件本身有可能被用户删除,这样的话,就比较麻烦了,目前虽然采用了文件权限来保证,不过还是无法保证root用户来删除,所以这个问题,目前还没有想到好的办法;