Locket

1.0.0 · maintenance · verified Sun Mar 29

Locket is a Python library (version 1.0.0, last released April 2022) that provides file-based locks for inter-process communication on both Linux and Windows. It offers a simple API for creating non-reentrant locks that behave similarly to `threading.Lock` instances, uniquely identified by the file path being locked. The library ensures that only one process can acquire a lock at a time for a given path, preventing conflicts when multiple processes access shared resources.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to use `locket.lock_file()` with a context manager for safe and automatic lock acquisition and release. It also shows the explicit `acquire()` and `release()` pattern, which requires careful handling to prevent deadlocks or `LockError` if `release()` is called on an unlocked lock. The `timeout` parameter prevents indefinite blocking.

import locket
import os
import time

# Define a lock file path, using an environment variable for flexibility
lock_file_path = os.environ.get('LOCKET_EXAMPLE_PATH', './my_app.lock')

print(f"Attempting to acquire lock on {lock_file_path}...")
try:
    # Acquire the lock using a context manager, with a 5-second timeout
    # If another process holds the lock, this will block for up to 5 seconds.
    # If the lock cannot be acquired, a LockError is raised.
    with locket.lock_file(lock_file_path, timeout=5):
        print(f"Lock acquired on {lock_file_path}. Performing critical action...")
        # Simulate work within the critical section
        time.sleep(2)
        print("Critical action complete. Lock will be released automatically.")
except locket.LockError:
    print(f"Could not acquire lock on {lock_file_path} within the timeout. Another process might hold it.")
except Exception as e:
    print(f"An unexpected error occurred: {e}")

print("\nDemonstrating explicit acquire/release (less recommended)...")
lock = None
try:
    # Acquire the lock explicitly
    lock = locket.lock_file(lock_file_path, timeout=1)
    lock.acquire()
    print(f"Lock acquired on {lock_file_path} (manual). Performing critical action...")
    time.sleep(1)
    print("Critical action complete (manual).")
finally:
    # Always ensure the lock is released, even if errors occur
    if lock:
        try:
            lock.release()
            print("Lock released (manual).")
        except locket.LockError:
            print("Warning: Attempted to release an already unlocked lock. This should not happen if `release()` is paired with `acquire()`.")

view raw JSON →