栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux下只允许程序运行一个实例

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux下只允许程序运行一个实例

Linux下只允许程序运行一个实例,这里想到两个方法,这个是用到ps,一个是用到文件锁。

1,ps方法:

        程序开始运行时读指定文件,如果匹配到程序名则已经有运行的进程,退出。若匹配不到则往文件写一些信息,程序退出时删除文件。



#include 
#include 
#include 
#include 

#define PROCESS_NAME "single_instance"
int isRunning();

int main()
{
    if(isRunning() == 1)
    {
        printf("%s has been run !n", PROCESS_NAME);
        return 0;
    }

    printf("run ok!n");
    system("ps | grep "single_instance" > process.pid");
    
    sleep(30);
    system("rm -rf process.pid");
    return 0;
}


int isRunning()
{
    char buf[128] = {0};
    FILE *fp = fopen("./process.pid", "rwb");

    if(fp != NULL)
    {
        int readLen = fread(buf, 1, sizeof(buf) - 1, fp);
        printf("read %d bytes data !n", readLen);
    }
    else
    {
        return 0;
    }

    if(strstr(buf, PROCESS_NAME) != NULL)
    {
        fclose(fp);
        return 1;
    }

    fclose(fp);
    return 0;
}

2,文件锁方法:

        程序开始运行时,往文件里写入进程号,并锁定文件;此时若再运行一个实例,因前一个实例已经锁定文件,此时是去锁定文件是失败的。


#include 
#include 
#include 
#include 
#include 
#include 
#include 
 
#define PROC_NAME "single_instance"
#define PID_FILE_PATH "/var/run/"
static int lockFile(int fd);
static int isRunning(const char *procname);
 

int g_fd = -1; 
int main()
{
    if(isRunning(PROC_NAME))
    {
        exit(-1);
    }
 
    printf("run ok, pid = %dn", getpid());
    sleep(30);
 
    if(g_fd != -1) 
    {
        close(g_fd);
    }

    return 0;
}
 
static int lockFile(int fd)
{
    struct flock fl;
    fl.l_type = F_WRLCK;
    fl.l_start = 0;
    fl.l_whence = SEEK_SET;
    fl.l_len = 0;
    fl.l_pid = getpid();  //当前进程号,可写可不写,写了后在用F_GETLK时则可以获取到pid

    int ret = fcntl(fd, F_SETLK, &fl);
    printf("file lock ret = %dn", ret);
    return ret;
}
 
static int isRunning(const char *procname)
{
    char buf[16] = {0};
    char fileName[128] = {0};
    snprintf(fileName, sizeof(fileName), "%s%s.pid", PID_FILE_PATH, procname);
 
    //创建文件时如果指定了 O_CREAT,则必须添加权限,否则可能无法读取文件而导致失败
    int g_fd = open(fileName, O_CREAT | O_RDWR, S_IRWXU);
    if(g_fd < 0)
    {
        printf("open file %s failed !n", fileName);
        return 1;
    }
 
    if(-1 == lockFile(g_fd))
    {
        // printf("%s is alread running !n", procname);
        struct flock fl;
        fl.l_type = F_WRLCK;
        fl.l_start = 0;
        fl.l_whence = SEEK_SET;
        fl.l_len = 0;
        
        
        if(fcntl(g_fd, F_GETLK, &fl) == 0)
        {
            printf("%s has been run, pid = %dn", PROC_NAME, fl.l_pid);
        }

        close(g_fd);
        return 1;
    }
    else
    {
        ftruncate(g_fd, 0);
        long pid = getpid();
        snprintf(buf, sizeof(buf), "%ld", pid);
        printf("write pid = %ld to %s!n", pid, fileName);
 
        write(g_fd, buf, strlen(buf) + 1);
        return 0;
    }
}

在两个命令行窗口运行如下:

 

 

原理:

程序在启动后,打开一个program.pid(或program.lock) 文件(无则创建)然后试图去设置文件锁,如果设置成功,则将该程序的进程pid写入该文件;如果加锁失败,那么说明已经有另外一个实例在运行,则退出此次启动。

Linux系统下就有很多这样的文件,如:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/894609.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号