方法一: 进程创建文件,给文件加锁,进程如果在运行,则文件被锁,其他进程访问失败,保证了进程的单例运行,进程退出,锁释放

https://www.cnblogs.com/scroot/p/5197331.html

script_instance.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
单例程序接口
"""
import os
import sys
import fcntl
import datetime

PID_FILE_DIR = '/var/run/'

s_fh = None

class ScriptInstance:
    def __init__(self, instance_name):
        #lock文件路径/var/run/进程名.lock
        self.__lock_file = PID_FILE_DIR + instance_name + '.lock'
        #keep-alive文件路径/var/run/进程名.alive
        self.__keep_alive_file = PID_FILE_DIR + instance_name + '.alive'

    def is_running(self):
        """
        判断该程序是否已经有实例在运行
        :return:True:已经有实例在运行;False:没有实例在运行
        """
        global s_fh
        if os.path.exists(self.__lock_file) is False:
            try:
                s_fh = open(self.__lock_file, 'w')
            except IOError:
                print ('Create file:%s failed' % self.__lock_file)
                sys.exit(1)

        if s_fh is None:
            try:
                s_fh = open(self.__lock_file, 'r+')
            except IOError:
                print ('Open file:%s failed' % self.__lock_file)
                sys.exit(1)

        try:
            fcntl.flock(s_fh, fcntl.LOCK_EX | fcntl.LOCK_NB)
        except IOError:
            return True

        return False

    def keep_alive(self):
        """
        向keep-alive文件中写入最新的心跳时间,用于softdog判断进程运行是否正常
        :return:True:设置成功;False:设置失败
        """
        try:
            fh = open(self.__keep_alive_file, 'w')
            fh.write(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
            fh.close()
            return True
        except IOError:
            pass
        return False

tets.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import sysfrom script_instance 
import ScriptInstance
if __name__ == '__main__':    
single = ScriptInstance("test")    
if single.is_running():        
	print("Last process is run")        
	sys.exit(0)    
print "Hello World"    
single.keep_alive()

 

2 shell 的单例

https://my.oschina.net/superwjc/blog/1810999

#单例执行
readonly LOCKFILE="/var/run/single_instance.pid"  #readonly 只读 类似 const
readonly FD=$(ls -l /proc/$$/fd | sed -n '$p' | awk '{print $9}') #https://www.cnblogs.com/emanlee/archive/2013/09/07/3307642.html $p和sed表最后一行
readonly LOCKFD=$(( ${FD}+1 ))

eexit() {
        local error_str="$@"
        echo -e ${error_str}
        exit 1
}

lock() {
        eval "exec ${LOCKFD}>${LOCKFILE}" # 将文件描述符指向某个文件
        flock -n ${LOCKFD} && echo "${BASHPID}" > "${LOCKFILE}" || eexit "\e[1;31m$0 is already running\x1b[0m"
}

unlock() {
        flock -u ${LOCKFD}
        eval "exec ${LOCKFD}>&-"
}

do_something() {
        mongo_softdog config 0
        mongo_softdog shard1 0
        mongo_softdog shard2 0
        mongo_softdog shard3 0
        mongo_softdog mongos 1
}

lock
do_something
if [[ $? == 0 ]]; then
        echo success
        unlock
else
        echo failed
fi

 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐