I have a python script that could be called by many processes on Linux. I am trying to ensure only one instance is allowed any time. Below is the code that I came up with: 1) opens a lockfile while in progress. 2)another instance detects this file is already opened so it quits with EBUSY.
Unfortunately, this does not handle when the process is killed (SIGKILL) - when the process is killed, the lockfile is not cleaned up, so another instance cannot run. Is there any better solution? Thanks.
#!/usr/bin/env python3.4
import os
from time import time, sleep
import argparse
import threading
import signal
import errno
from pathlib import Path
# globals
shutdown = False
lockFile = '/var/run/tlock'
def pickWork():
rc = 0
# check if another instance is in-progress
lockDir = os.path.dirname(lockFile)
if not Path(lockDir).is_dir():
os.makedirs(lockDir, exist_ok=True)
if Path(lockFile).is_file():
print('this job in progress, try after 5 min')
return errno.EBUSY
# create lock file so as second instance fails right away.
open(lockFile, 'w')
while not shutdown:
# processReqs()
print('sleeping for 5 sec')
sleep(5) # for now
# cleanup
if Path(lockFile).is_file():
os.remove(lockFile)
return rc;
def signalHandler(signum, frame):
global shutdown
print("Received signal: {0}, graceful shutdown in progress".format(str(signum)))
shutdown = True
def argParse():
parser = argparse.ArgumentParser("Simple Test Program ")
get = parser.add_argument_group("get user input")
get.add_argument("-g", "--get", action="store_true", help="get input")
args = parser.parse_args()
if not (args.get):
parser.print_help()
return None
return args
def Start():
args = argParse()
if args is None:
print('specify args')
exit(1)
signal.signal(signal.SIGINT, signalHandler)
signal.signal(signal.SIGQUIT, signalHandler)
signal.signal(signal.SIGTERM, signalHandler)
if args.get:
#t = threading.Thread(name='pickWork', target=pickWork)
#t.start()
#t.join()
rc = pickWork()
print("EXITED with rc=", rc)
if __name__ == "__main__":
Start()