Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to perform file-locking on Windows without installing a new package

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.)

like image 859
dbliss Avatar asked May 25 '15 14:05

dbliss


People also ask

How does file locking work in Windows?

File locking is a mechanism that restricts access to a computer file, or to a region of a file, by allowing only one user or process to modify or delete it at a specific time and to prevent reading of the file while it's being modified or deleted.

How do you lock a file?

Right-click a file (or click the ellipses (...)) to open the More Options menu. Click Lock. Choose a duration for the lock. If you choose unlimited, the file will be locked until you unlock it manually.

Does SMB support file locking?

SMB file lockingSMB clients that mount file shares can leverage file system locking mechanisms to manage access to shared files. These include: Whole file access sharing for read, write, and delete.


1 Answers

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.

like image 148
cdarke Avatar answered Oct 20 '22 11:10

cdarke