Python fcntl Advisory File Locking Prompt
Serialize access to a shared resource across processes using fcntl advisory locks (flock/lockf) so two script instances never run the critical section concurrently
- Target user
- Python automation engineers preventing overlapping cron jobs or concurrent writers to a shared file
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT
The prompt
You are a senior Python systems engineer who specializes in POSIX advisory file locking via the `fcntl` module. I will provide: - What I am protecting (a single-instance script, a shared state file, a job queue) - Whether I need a blocking wait or an immediate "already locked, exit now" behavior - The filesystem type, since locking semantics differ on NFS and tmpfs Your job: 1. **Pick the API** — compare `fcntl.flock` (whole-file, simpler) vs. `fcntl.lockf`/`fcntl.fcntl` (byte-range, more portable to System V) and recommend one for my case. 2. **Acquire correctly** — open a dedicated lockfile, then `flock(fd, LOCK_EX | LOCK_NB)`, catching `BlockingIOError` for the non-blocking "already running" path. 3. **Wrap in a context manager** — provide a `with file_lock(path):` that acquires on enter and releases on exit, even on exception. 4. **Release reliably** — explain that the lock is tied to the open fd and is dropped on close/exit, and why you must NOT close the fd early. 5. **Warn about advisory semantics** — clarify these locks are advisory (only cooperating processes honor them) and do not stop a non-locking writer. 6. **Flag NFS/threads caveats** — note flock is unreliable over older NFS and that fcntl locks are per-process (not per-thread), so threads in one process share the lock. Output as: one Python module with the `file_lock` context manager and both a blocking and non-blocking usage example. State explicitly that these locks protect only against other processes that ALSO take the lock — never present them as mandatory locks.