Install pip install psutil
Store pid and command line of current running instance.
NOTE: This will not work in Windows due to fcntl
. Refer to tendo.
import fcntlimport psutillockfile_fp = Nonedef check_instance_running(lockfile): global lockfile_fp lockfile_fp = open(lockfile, 'a') try: fcntl.lockf(lockfile_fp, fcntl.LOCK_EX | fcntl.LOCK_NB) lockfile_fp.seek(0) lockfile_fp.truncate() # lockfile_fp.write(str(os.getpid())) lockfile_fp.write(json.dumps({ 'pid': os.getpid(), 'cmdline': psutil.Process(os.getpid()).cmdline() })) lockfile_fp.flush() running = False except IOError: with open(lockfile, 'r') as fp: # running = fp.read() running = json.loads(fp.read()) # running = True return running
Only allow single instance to run
lockfile = 'test.lock'data = check_instance_running(lockfile)if data: raise Exception(f"Already running: {data['pid']}")print('START')while True: print('.', end='', flush=True) time.sleep(5)
Kill previous instance
lockfile = 'test.lock'data = check_instance_running(lockfile)if data: p = psutil.Process(data['pid']) # check cmdline, as pid could be recyled cmdline = p.cmdline() # check script and arguments must be the same # if (p.cmdline() == data['cmdline']): # check if same script file only: cmdline[0]==python, cmdline[1]==scriptname, cmdline[2..]==arguments if len(cmdline) >= 2 and len(data['cmdline']) >= 2 and cmdline[1] == data['cmdline'][1]: print(f"Kill Previous Process: {data['pid']}") p.terminate() p.wait() # create new lock file util.check_instance_running(lockfile)print('START')while True: print('.', end='', flush=True) time.sleep(5)