How can I avoid running a python script multiple times? Implement file locking.

March 13th, 2009 mysurface Posted in Developer, python | Hits: 203439 | 7 Comments »

Sometimes we just need a single instance of the python script to run at a time. Meaning, the python script itself should detects whether any instances of himself are still running and act accordingly.

Well, how to do it?

The idea is simple, the first instance of the python script will open a file, and lock it. Therefore when the consequent instances try to lock the file, it will fails.

The code is simple too.


import fcntl
def lockFile(lockfile):
    fp = open(lockfile, 'w')
    try:
        fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
    except IOError:
        return False

    return True

The function will try to lock the file specified by me, if it success, return True, else return False.

From any point of my codes, I’ll do


if not lockFile(".lock.pod"):
        sys.exit(0)

Interesting?

7 Responses to “How can I avoid running a python script multiple times? Implement file locking.”

  1. Nice. Thanks.

  2. It is interesting, but partly because I can’t see much difference between writing an ordinary file checking for its existence. I can’t seem to find any differences on the command line between the two files using stat nor ls, although they must exist.

    Also, it might be worth mentioning LOCK_UN as a param to fcntl.lockf for the purpose of unlocking. :)

  3. The nice thing is that the lock will be dropped when the program terminates.

  4. Hmm, strange. I tried this, but it didn’t seem to work. I even tried copy-pasting your example, but it didn’t work either. It’s such a simple little snippet that I don’t see what could possibly be wrong with it.

    Guess I’m off to find another way to do this.

  5. The problem is that the nuilt-in open() function was used which return a file object. You need to use os.open instead which return an integer file descriptor.

    def lockFile(lockfile):
    fd = os.open(lockfile, os.O_CREAT | os.O_TRUNC | os.O_WRONLY)
    try:
    # Request exclusive (EX) non-blocking (NB) advisory lock.
    fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
    except IOError:
    return False

    return True

  6. Florian Mycka Says:

    Hey there… i was searching and trying the whole day about this exclusive lock to avoid multiple instances. I found so many code snippets, basically all doing the same thing – but non worked every time. Also this one! Sometimes the file was ex. locked and the second instance did not start, but most of the time it started. And I cannot say why.

    Now I googled “fcntl.lockf seems not to work” finding the following link http://stackoverflow.com/questions/5369870/file-lock-not-working-as-expected

    “Found the solution myself in the end. It was to use fcntl.flock() instead of fcntl.lockf(), with the exact same parameters. Not sure why that made a difference.” by Felix.

    I changed this in the above mentioned function – I cannot believe this! It works fine now… man, what a pitfall.

  7. Have you considered adding some differing opinions to your article? I think it might enhance everyones understanding.

Leave a Reply