Python Locking and Single-Instance Scripts
A cron job that sometimes takes longer than its interval will eventually run twice at once. The obvious fix - a lock file - has a failure mode that is worse than the problem: a run killed while holding it locks the job out permanently. This guide shows the collision, the stale lock, and fcntl.flock, which the kernel releases when the holder dies no matter how it died.
OS and Process Automation Guide 22 of 39 Intermediate
- Control nodeUbuntu 26.04 LTS
- Python3.14.4
- requests2.34.2
- paramiko5.0.0
- TimeAbout 18 min
fcntl is Unix-only and always has been; on Windows the equivalent is msvcrt.locking. unlink(missing_ok=True) needs Python 3.8.
- pytest9.1.1
- PyYAML6.0.3
- boto3 / botocore1.43.78
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| RUNNER01 | 192.168.0.27 | Ubuntu 26.04 LTS | Control node - every script in this path runs here | 2 Core | 4 GB | 50 GB |
This guide includes
Use this for any job scheduled more often than it reliably finishes. This matters because two copies will eventually overlap - and a lock file left behind by a killed run blocks every run after it, unless the kernel is the one holding the lock.
- watching two runs collide
- claiming a lock file without a race
- seeing what happens when a run dies holding it
- using a lock the kernel releases for you, even when the holder is killed
- wrapping it in a context manager, so it cannot be forgotten
Before you start
-
Two runs at once
-
A lock file claimed without a race
-
And what happens when a run dies holding it
-
A lock the kernel releases for you
-
The file left behind is harmless
-
Even when the holder is killed
-
A context manager, so it cannot be forgotten