Chinaunix首页 | 论坛 | 博客
  • 博客访问: 742653
  • 博文数量: 141
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1115
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-17 14:32
个人简介

小公司研发总监,既当司令也当兵!

文章分类

全部博文(141)

分类: LINUX

2016-10-09 14:02:58

在开发中,往往希望一个应用程序在一台设备上只启动一个实例;但有时候,应用程序可能由其他程序、脚本启动,难免会重复执行,导致启动多个实例。刚刚在项目中就遇到一个:一个进程可能会开机启动,也可以由一个网络状态变更脚本触发启动;大多数情况下没有问题,但在个别特例网络环境中,可能会反复调度脚本,导致该程序多次启动,相互干扰导致运行异常。

为了避免这个问题,对启动脚本做了修改:在shell脚本中,启动该进程时,记录一个pid文件,如果该脚本被多次调度,那么通过判断pid文件的存在来避免重复启动进程。

上面的方法多少情况下简单有效,但如果多个脚本都可以启动,那么维护脚本就变得复杂。有没有方法在进程内部进行判断,来避免重复启动呢?答案是肯定的。接下来我们介绍一种采用文件锁的方式来避免进程启动多个实例。

思路:借鉴上面shell采用pid文件的方式,我们通过生成一个pid文件,并且采用write lock锁住该文件;如果有重复启动的情况,后面的进程再尝试锁住该pid文件时会失败,说明已经有实例在运行了,那么该进程自动退出,从而保证只有一个实例运行。

代码如下:

#include 

#include 

#include 

#include 

#include

 

#define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)  

 

static int tryLockPidFile(int fd)

{

        struct flock fl;

 

        fl.l_type = F_WRLCK;  /* write lock */

        fl.l_start = 0;

        fl.l_whence = SEEK_SET;

        fl.l_len = 0;  //lock the whole file

      fl.l_pid = getpid();

 

        return(fcntl(fd, F_SETLK, &fl));

}

 

static int isInRunning(const char *filename)

{

        int fd;

        char buf[16];

 

        fd = open(filename, O_RDWR | O_CREAT, LOCKMODE);

        if (fd < 0)

       {

                printf("can't crate/open %s\n", filename);

                exit(1);

        }

 

        /* try to lock the file */

        if (tryLockPidFile (fd) == -1)

       {

                if (errno == EACCES || errno == EAGAIN)

              {   

                    close(fd);

                    return 1;

                }

                printf("can't lock %s\n", filename);

                exit(1);

        }

      

        /* write pid */

        ftruncate(fd, 0);

        sprintf(buf, "%ld", (long)getpid());

        write(fd, buf, strlen(buf) + 1);

 

       // do not close the fd to keep the file lock last all the time of program life

       // if close the file, the file-lock close automatic

       // close(fd);

        return 0;

}

阅读(4011) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~