Skip to main content.
December 1st, 2006

Python - How to Lock a File in Windows

If you have a situation where multiple programs could be writing to the same file at the same time, file locking it is a simple way to keep things safe and coordinated. I’ve found the portalocker code/module to be the best way to achieve this in Windows. Below is some sample code for using this module, but be sure to notice the trick in line 5, or you’ll be moderately confused for three months and think the code is working when it’s not (more on that after the sample.).

Sample Usage:

import portalocker
#access the file you want to lock
token=file('token.txt','r+') #use r+ for some reason ...
#Lock the file
portalocker.lock(token,portalocker.LOCK_EX|portalocker.LOCK_NB)
#Brag about it, or perhaps use the file ...
print 'I have this file! No one can use it!'
time.sleep(10)
#Relinquish
token.close()
print 'Ok, you can use it now'

Notice that weird looking “portalocker.LOCK_EX|portalocker.LOCK_NB” on line 5? That’s what made it work for me. I don’t know how or why but finally got this idea from a google code search on portalocker.

If anyone knows why “portalocker.LOCK_EX|portalocker.LOCK_NB” works while only “LOCK_EX” works but just makes other programs hang at opening token.txt, and “LOCK_NB” and “LOCK_SH” don’t work at all, then you’ll get a $5 dollar gift card for Answer My Searches (assuming I ever sold merchandise on this site which I can’t fathom, oh and it expires in 6 months! .. but I’d still appreciate the answer :-)

Update:
Jody, from Gaithersburg, Maryland writes in that LOCK_EX is for blocking access and LOCK_EX|portalocker.LOCK_NB is for not blocking which I suppose means causing another program to raise an error when accessing a locked file as shown in this link. Enjoy the gift card, Jody!

Tags: , , , , , ,

Posted by Greg Pinero (Primary Searcher) in win32, Python

This entry was posted on Friday, December 1st, 2006 at 12:33 pm and is filed under win32, Python. You can follow any responses to this entry through the comments RSS 2.0 feed. Both comments and pings are currently closed.

4 Responses to “Python - How to Lock a File in Windows”

  1. Observer says:

    From the flock manual page:

    LOCK_SH - Place a shared lock. More than one process may hold a shared lock for a given file at a given time.

    LOCK_EX - Place an exclusive lock. Only one process may hold an exclusive lock for a given file at a given time.

    A call to flock() may block if an incompatible lock is held by another process. To make a non-blocking request, include LOCK_NB (by ORing)
    with any of the above operations.

  2. Greg Pinero (Primary Searcher) says:

    Thanks, Observer. That explains it even better.

  3. Jim says:

    The simple rules for windows LockfileEx (which is what is used at the lowest level) are the following:

    LOCK_EX == Only the locking process can read or write to the file while the lock is held. Anyone else who tries to open the file will get an error.

    LOCK_SH == Only the locking process can read, but others can access the file read-only.

    LOCK_NB == If you make a call to lock a file and another process has a lock on the file (or if you are making a LOCK_EX and another process has an open filehandle on the file in question) then LockfileEx has to decide what to do: wait for the lcok to be released and grab it as soon as it is available or return to the caller and tell them that the lock failed. If LOCK_NB is a part of the call to LockfileEx then the caller will return instantly with a succeed/fail result, if LOCK_NB is not provided then the caller will wait (blocking on the LockfileEx call) until the original lock is released and it can grab the lock.

    BTW, portalocker is old and out of date. Check out the locking info at http://aspn.activestate.com/ASPN/docs/ActivePython/2.4/pywin32/Windows_NT_Files_.2d.2d_Locking.html
    (but change self.highbits from 0xffff0000 to -0×7fff0000 if you decide to use the code in that particular doc under python 2.4)

  4. Peter S says:

    Some web pages says that highbits should be 0×7fff0000, other put a minus sign in front of the hex number (-0×7fff0000). Why is the number negative and why is it not -0×80000000, which is the smallest int in python?

    /regards Peter