How to Lock a File with Python FileLock

In this tutorial we will discuss how to use the Python FileLock module to Lock a File for access. This module has full support for Unix and Windows, and partial support for other platforms.

The FileLock module is used to prevent possible synchronization problems when multiple threads or processes are reading/writing to/from the same file. This type of synchronization problem is known as a Race Condition.

With FileLock we “lock” the file for the duration that a process accesses it. While this process is reading or writing to/from it, no other process will be allowed access to the file. Only when the current process is done, will another process be allowed to access it (one at a time of course). This type of condition is known as mutual exclusion.

The useful thing about this package is that we can use it to maintain synchronization between different python programs (different processes). Otherwise if you just want to maintain synchronization/mutual exclusion between threads in the same process (same python program), regular thread locks and/or binary semaphores will be enough.


How to use FileLock in Python

Using FileLock is fairly straightforward and very similar to the locking mechanisms from other Python libraries.

file = "example.txt"
lockfile = "example.txt.lock"

First we will save the filepath/filename of our file in two variables as shown above. file holds the file path to the file we wish to access. lockfile holds the filepath to the lock file.

The lock file determines whether a thread/process should be allowed to access the file. (We can’t use a regular variable lock here like we usually do because we need the lock to be accessible to other processes if necessary)

The name of the lock file is typically the name of the original file + “.lock”.

lock = FileLock(lockfile, timeout = 5)

Here we create the lock using the lockfile and FileLock Class. We can also choose to pass an optional argument “timeout” which sets a timer on how long a process/thread will wait for the lock.

In our case, a process will wait no longer than 5 seconds for the Lock, after which it will raise a Timeout exception.

Here is the main logic.

lock.acquire()
try:
    with open(file, "a") as f:
        f.write("Add some data")
finally:
    lock.release()

First we acquire the lock. We can also pass a timeout parameter here which will over-ride the timeout set earlier by FileLock(). If the lock is successfully acquired, we will go ahead and write some data to the file.

And “finally” after writing the data we will release the lock. (Using the try/except block here is not necessary)


Complete Code

Here is the complete code. Try running it yourself to see the magic!

from filelock import FileLock, Timeout

file = "example.txt"
lockfile = "example.txt.lock"

lock = FileLock(lockfile, timeout = 5)

lock.acquire()
try:
    with open(file, "a") as f:
        f.write("Add some data")
finally:
    lock.release()

Recursive File Lock

File locks are also recursive, which means that within the critical section for a lock, we may attempt to acquire it again. In certain libraries this behavior is not support, but FileLock does.

The below code features two functions, func_1 and func_2. This first function, func_1 has the same code from the previous section with one addition. We make a call to func_2 in it, which also attempts to access the same lock.

Non-recursive locks would not allow you to access the lock again. FileLock however creates recursive locks, which can be acquired multiple times within the same critical section.

from filelock import FileLock, Timeout
from threading import Lock

file = "example.txt"
lockfile = "example.txt.lock"

lock = FileLock(lockfile, timeout = 5)

def func_2(lock):
    lock.acquire()
    try:
        with open(file, "a") as f:
            f.write("Function#2: Add some data/n")
    finally:
        lock.release()

def func_1(lock):
    lock.acquire()
    try:
        with open(file, "a") as f:
            f.write("Function#1: Add some data/n")
            func_2(lock)
    finally:
        lock.release()
        
func_1(lock)

The code will append two new lines to an existing file or will create a new file with these two lines.


This marks the end of the How to Lock a File with Python FileLock Tutorial. Any suggestions or contributions for CodersLegacy are more than welcome. Questions regarding the tutorial content can be asked in the comments section below.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments