7

I've added code to a Python package (brian2) that places an exclusive lock on a file to prevent a race condition. However, because this code includes calls to fcntl, it does not work on Windows. Is there a way for me to place exclusive locks on files in Windows without installing a new package, like pywin32? (I don't want to add a dependency to brian2.)

5
  • Do you have module msvcrt? Commented May 25, 2015 at 14:38
  • @cdarke i don't have it, but do you think that's just because i'm on a unix machine? does it come standard only on windows machines? Commented May 25, 2015 at 17:36
  • 1
    I would not expect it to be on a UNIX machine - the question is about Windows, isn't it? I have checked, and it is part of the Python standard library for Windows. Unfortunately it is difficult to produce portable file locking code because the operations are so different (see my post). Commented May 25, 2015 at 19:10
  • @cdarke thanks for checking that. i'm guessing fcntl doesn't come with the standard library on windows? Commented May 26, 2015 at 1:00
  • That's correct, fcntl is not bundled with Python 2 or 3 on Windows. Commented May 26, 2015 at 8:23

1 Answer 1

6

Since msvcrt is part of the standard library, I assume you have it. The msvcrt (MicroSoft Visual C Run Time) module only implements a small number of the routines available in the MS RTL, however it does implement file locking. Here is an example:

import msvcrt, os, sys REC_LIM = 20 pFilename = "rlock.dat" fh = open(pFilename, "w") for i in range(REC_LIM): # Here, construct data into "line" start_pos = fh.tell() # Get the current start position # Get the lock - possible blocking call msvcrt.locking(fh.fileno(), msvcrt.LK_RLCK, len(line)+1) fh.write(line) # Advance the current position end_pos = fh.tell() # Save the end position # Reset the current position before releasing the lock fh.seek(start_pos) msvcrt.locking(fh.fileno(), msvcrt.LK_UNLCK, len(line)+1) fh.seek(end_pos) # Go back to the end of the written record fh.close() 

The example shown has a similar function as for fcntl.flock(), however the code is very different. Only exclusive locks are supported. Unlike fcntl.flock() there is no start argument (or whence). The lock or unlock call only operates on the current file position. This means that in order to unlock the correct region we have to move the current file position back to where it was before we did the read or write. Having unlocked, we now have to advance the file position again, back to where we were after the read or write, so we can proceed.

If we unlock a region for which we have no lock then we do not get an error or exception.

Sign up to request clarification or add additional context in comments.

3 Comments

is the lock automatically released when the file is closed?
@dbliss: I'm not sure, and I don't have a Windows machine handy right now to try it. The doc does not say, so I would not bet on it. By the way, I put a demo here: darkeside.blogspot.co.uk/2010/11/…
from what i can tell it is, but i also don't have a windows machine to test this on.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.