flock(2)
Apply or remove an advisory whole-file lock tied to an open file description.
- Since
- 4.2BSD; Linux 2.0check your kernel →
- glibc
- unknown
- System
- Linux
- Man page
- flock(2)
Synopsis
#include <sys/file.h>
int flock(int fd, int op);Rod's take
The pidfile you were about to write is broken three ways: test-and-set races, a SIGKILL leaves it stale forever, and PIDs get recycled. flock(2) is one kernel operation on an open file description, so when the holder dies, however it dies, the lock goes with it. Wrap the cron job in flock -n and an overlapping run just exits. Lock the contested resource, not the job, and share the lock file across every script that touches it. It's advisory: anything that doesn't ask walks straight through. Across hosts or NFS, use something built for distributed locking, not a file and a prayer.
Flags and arguments that matter
| Name | What it does |
|---|---|
| LOCK_SH | Shared lock; many processes can hold one at the same time. |
| LOCK_EX | Exclusive lock; only one holder at a time. |
| LOCK_UN | Release the lock held via this open file description. |
| LOCK_NB | OR in to fail with EWOULDBLOCK instead of blocking when the lock is held. |
Errors you will actually hit
| errno | Meaning |
|---|---|
| EWOULDBLOCK | The file is locked and LOCK_NB was given. |
| EINTR | A caught signal interrupted the wait for the lock. |
| EBADF | fd is not an open file descriptor. |
| EINVAL | op is invalid. |
| ENOLCK | The kernel ran out of memory for lock records. |
Example
# crontab: skip this run if the last one is still going
# */5 * * * * /usr/bin/flock -n /var/lock/report.lock /usr/local/bin/report.sh
#!/bin/bash
# self-locking script: fd 9 holds the lock until the script exits
exec 9>/var/lock/job.lock
flock -n 9 || { echo "already running"; exit 0; }
# ... work ...
# wait up to 60s instead of skipping
flock -w 60 /var/lock/job.lock /usr/local/bin/job.shTrimmed from the full walkthrough in Your cron job is running twice and that's why the numbers are wrong.
BSD equivalent
FreeBSD: flock(2) (appeared in 4.2BSD). OpenBSD: flock(2) (first appeared in 4.1cBSD per its man page). On the modern BSDs flock and fcntl locks interact; on Linux they don't (except over NFS/SMB).
The long version, from the console
Sources
Version numbers are read off the cited man pages, not memory. Spot one that's wrong? Tell Rod.
