Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python fcntl does not lock as expected

Tags:

python

fcntl

On a Debian-based OS (Ubuntu, Debian Squeeze), I'm using Python (2.7, 3.2) fcntl to lock a file. As I understand from what I read, fnctl.flock locks a file in a way, that an exception will be thrown if another client wants to lock the same file.

I built a little example, which I would expect to throw an excepiton, since I first lock the file, and then, immediately after, I try to lock it again:

#!/usr/bin/env python # -*- coding: utf-8 -*- import fcntl fcntl.flock(open('/tmp/locktest', 'r'), fcntl.LOCK_EX) try:     fcntl.flock(open('/tmp/locktest', 'r'), fcntl.LOCK_EX | fcntl.LOCK_NB) except IOError:     print("can't immediately write-lock the file ($!), blocking ...") else:     print("No error") 

But the example just prints "No error".

If I split this code up to two clients running at the same time (one locking and then waiting, the other trying to lock after the first lock is already active), I get the same behavior - no effect at all.

Whats the explanation for this behavior?

EDIT:

Changes as requested by nightcracker, this version also prints "No error", although I would not expect that:

#!/usr/bin/env python # -*- coding: utf-8 -*- import fcntl import time fcntl.flock(open('/tmp/locktest', 'w'), fcntl.LOCK_EX | fcntl.LOCK_NB) try:     fcntl.flock(open('/tmp/locktest', 'w'), fcntl.LOCK_EX | fcntl.LOCK_NB) except IOError:     print("can't immediately write-lock the file ($!), blocking ...") else:     print("No error") 
like image 976
Wolkenarchitekt Avatar asked Mar 28 '12 12:03

Wolkenarchitekt


1 Answers

Old post, but if anyone else finds it, I get this behaviour:

>>> fcntl.flock(open('test.flock', 'w'), fcntl.LOCK_EX) >>> fcntl.flock(open('test.flock', 'w'), fcntl.LOCK_EX | fcntl.LOCK_NB) # That didn't throw an exception  >>> f = open('test.flock', 'w') >>> fcntl.flock(f, fcntl.LOCK_EX) >>> fcntl.flock(open('test.flock', 'w'), fcntl.LOCK_EX | fcntl.LOCK_NB) Traceback (most recent call last):   File "<stdin>", line 1, in <module> IOError: [Errno 35] Resource temporarily unavailable >>> f.close() >>> fcntl.flock(open('test.flock', 'w'), fcntl.LOCK_EX | fcntl.LOCK_NB) # No exception 

It looks like in the first case, the file is closed after the first line, presumably because the file object is inaccessible. Closing the file releases the lock.

like image 177
philh Avatar answered Oct 06 '22 06:10

philh