• 程序单实例运行


    说明

    有时我们需要程序同时只能有一个实例在运行,或是受于资源限制或是受于锁或者其他原因。
    因此,需要一直机制在程序启动时候判断是否有别的实例已经在运行。这里有集中方案。

    1. 用bash脚本或者supervisor之类管理工具判断,这种受于程序名字限制。
    2. 用文件锁。程序启动时候往文件写入pid或其他信息,退出时释放文件锁。其实本质上是独占写,程序退出时候会释放写锁。

    这里我用了第二种方式,以最简单的 c 程序给出示例。

    代码

    
    #define dbg_time(fmt, arg...) do{ printf("[%s:%d:%s] "fmt"
    ", __FILE__, __LINE__, __FUNCTION__, ##arg);}while(0)
    #define log_warn(fmt, arg...) dbg_time("33[40;33m"fmt"33[0m", ##arg)
    #define log_err(fmt, arg...)  dbg_time("33[40;31m"fmt"33[0m", ##arg)
    #define log_norm(fmt, arg...)  dbg_time("33[40;37m"fmt"33[0m", ##arg)
    
    #define LOCKFILE "/var/run/xxx.pid"
    // 带w的函数是阻塞调用
    #define lockrd(fd, offset, whence, len)     setlock(fd, F_SETLK, F_RDLCK, offset, whence, len)
    #define lockrdw(fd, offset, whence, len)    setlock(fd, F_SETLKW, F_RDLCK, offset, whence, len)
    #define lockwr(fd, offset, whence, len)     setlock(fd, F_SETLK, F_WRLCK, offset, whence, len)
    #define lockwrw(fd, offset, whence, len)    setlock(fd, F_SETLKW, F_WRLCK, offset, whence, len)
    #define unlock(fd, offset, whence, len)     setlock(fd, F_SETLK, F_UNLCK, offset, whence, len)
    
    int setlock(int fd, short cmd, short type, off_t offset, int whence, off_t len) {
        struct flock lock;
        lock.l_type = type; /* F_RDLCK, F_WRLCK, F_UNLCK */
        lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
        lock.l_start = offset; /* byte offset, relative to l_whence */
        lock.l_len = len; /* #bytes (0 means to EOF) */
        lock.l_pid = getpid();
        return (fcntl(fd, cmd, &lock));
    }
    
    void IsRunning(void) {
        char buf[32];
        gLockfd = open(LOCKFILE, O_RDWR|O_CREAT, 0644);
        if (gLockfd < 0) {
            log_err("Open %s fail!
    ", LOCKFILE);
            exit(1);
        }
        /* add lock*/
        if (lockwr(gLockfd,  0, SEEK_SET, 0) < 0) {
            log_warn("Add lock failed maybe another instance is running");
            close(gLockfd);
            exit(1);
        }
    
        ftruncate(gLockfd, 0);
        snprintf(buf, 32, "%ld", (long)getpid());
        write(gLockfd, buf, strlen(buf)+1);
        return;
    }
    
  • 相关阅读:
    Vue.js组件理解
    Vue.js 基础知识
    JS-WEB-API 整理
    JS面向对象基础
    JS基础知识系统整理(不断更新)
    图解关于pageX,pageY,screenX,screenY,clientX,clientY的区别
    妙味JS学习记录(二)
    Ajax全接触笔记
    妙味JS学习记录(一)
    c#设计模式系列:状态模式(State pattern)
  • 原文地址:https://www.cnblogs.com/sinpo828/p/10678949.html
Copyright © 2020-2023  润新知