Berta Dénes Berta Dénes - 3 months ago 18
Python Question

portalocker does not seem to lock

I have a sort of checkpoint file which I wish to modify sometimes by various python programs. I load the file, try to lock it using portalocker, change it, than unlock and close it.

However, portalocker does not work in the simplest case.
I created a simple file:

$echo "this is something here" >> test
$python
Python 3.5.2 (default, Jul 5 2016, 12:43:10)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import portalocker
>>> f = open("test",'w')
>>> portalocker.lock(f, portalocker.LOCK_EX)


Meanwhile I can still open it in another terminal:

$python
Python 3.5.2 (default, Jul 5 2016, 12:43:10)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> fl = open("test",'w')
>>> fl.write("I can still overwrite this\n")
>>> fl.close()


Then I close the first one, and check the file:

>>> portalocker.unlock(f)
>>> f.close()
>>>
$ cat test
I can still overwrite this


What am I doing wrong?

Answer

The problem is that, by default, Linux uses advisory locks. To enable mandatory locking (which you are referring to) the filesytem needs to be mounted with the mand option. The advisory locking system actually has several advantages but can be confusing if you're not expecting it.

To make sure your code works properly in both cases I would suggest encapsulating both of the open calls with the locker.

For example, try this in 2 separate Python instances:

import portalocker

with portalocker.Lock('test') as fh:
    ...

Ps: I'm the maintainer of the portalocker package