Implementing file locks using Python's with statement

File lock

I really love Python's with statement. It's great for implementing locks and transactions.

Today we had a problem where a script is run multiple times simultaneously. The easy way to solve this issue is via file locks.

The standard way of implementing a file lock could be like this:

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

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

This works, but it can be much more beautiful and pythonic using the with statement.

Here is how a file lock implemented via with statement looks like:

import time

with file_lock('/tmp/my_script.lock'):
    print "I am here and I am sleeping for 10 sec..."
    time.sleep(10)

Here is the implementation (should be cross platform, but not tested):

import os, sys
from contextlib import contextmanager

@contextmanager
def file_lock(lock_file):
    if os.path.exists(lock_file):
        print 'Only one script can run at once. '\
              'Script is locked with %s' % lock_file
        sys.exit(-1)
    else:
        open(lock_file, 'w').write("1")
        try:
            yield
        finally:
            os.remove(lock_file)

Further reading:

Code · Code improvement · Code rewrite · Python · Tips 30. Jun 2010
© Amir Salihefendic. Powered by Skeletonz.