I have a Thread-extending class that is supposed to run only one instance at a time (cross-process). In order to achieve that, I’m trying to use a file lock. Here are bits of my code:
class Scanner(Thread):
def __init__(self, path):
Thread.__init__(self)
self.lock_file = open(os.path.join(config.BASEDIR, "scanner.lock"), 'r+')
fcntl.lockf(self.lock_file, fcntl.LOCK_EX | fcntl.LOCK_NB)
# Stuff omitted
def run(self):
logging.info("Starting scan on %s" % self.path)
# More stuff omitted
fcntl.lockf(self.lock_file, fcntl.LOCK_UN)
I was expecting the lockf call to throw an exception if a Scanner thread was already running and not initialize the object at all. However, I can see this in the terminal:
INFO:root:Starting scan on /home/felix/Music
INFO:root:Starting scan on /home/felix/Music
INFO:root:Scan finished
INFO:root:Scan finished
Which suggests that two Scanner threads are running at the same time, no exception thrown. I’m sure I’m missing something really basic here, but I can’t seem to figure out what that is. Can anyone help?
Found the solution myself in the end. It was to use
fcntl.flock()instead offcntl.lockf(), with the exact same parameters. Not sure why that made a difference.