0

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()
cpuNram
  • 205
  • 2
  • 12

0 Answers0