--- name: flock signature: 'flock FILEHANDLE,OPERATION' since: 5.0 status: documented categories: ["I/O"] --- ```{index} single: flock; Perl built-in ``` *[I/O](../perlfunc-by-category)* # flock Place an advisory lock on an open file. `flock` is Perl's portable file-locking primitive. It calls the underlying `flock(2)`, `fcntl(2)`, or `lockf(3)` — whichever the platform provides — on `FILEHANDLE` and blocks by default until the requested lock can be granted. Locks cover the **whole file**, never a byte range, and are **advisory**: they coordinate only among processes that also call `flock` on the same file. Code that ignores the lock can still read or modify the contents. ## Synopsis ```perl flock FILEHANDLE, OPERATION ``` ## What you get back True on success, false on failure (with [`$!`](../perlvar) set). Always check the return value — with `LOCK_NB` a failure is the normal "someone else holds it" signal, not an error: ```perl flock($fh, LOCK_EX | LOCK_NB) or die "already locked: $!"; ``` On a platform that implements none of `flock(2)`, `fcntl(2)` locking, or `lockf(3)`, `flock` raises a fatal error rather than returning false. On Linux (pperl's only supported platform) this never happens. ## OPERATION values `OPERATION` is one of the mutually exclusive request types, optionally bitwise-or'ed with the non-blocking flag. Traditional numeric values are `1`, `2`, `4`, `8` but portable code imports the symbolic names from [`Fcntl`](../../Fcntl), either individually or as a group via the `:flock` tag: ```perl use Fcntl qw(:flock); ``` - `LOCK_SH` — shared lock. Multiple processes may hold a shared lock on the same file simultaneously. Used for readers. - `LOCK_EX` — exclusive lock. Only one process may hold it; no other process may hold any lock on the file at the same time. Used for writers. - `LOCK_UN` — release whatever lock this filehandle currently holds. - `LOCK_NB` — bitwise-or with `LOCK_SH` or `LOCK_EX` to make the call non-blocking; `flock` returns false immediately if the lock cannot be granted, instead of waiting. An `flock` call with a new mode atomically replaces an existing lock on the same filehandle (for example, upgrading `LOCK_SH` to `LOCK_EX`). ## Global state it touches - Sets [`$!`](../perlvar) on failure. - Flushes `FILEHANDLE`'s output buffer before locking or unlocking, so locked-region data hits the OS before another process can see the lock state change. ## Examples Exclusive lock for a writer, blocking until granted: ```perl use Fcntl qw(:flock); open my $fh, ">>", "counter.log" or die $!; flock($fh, LOCK_EX) or die "lock failed: $!"; print $fh "tick\n"; flock($fh, LOCK_UN) or die "unlock failed: $!"; close $fh; ``` Non-blocking attempt — skip the work if another process is already running: ```perl use Fcntl qw(:flock); open my $fh, ">", "/var/run/myjob.lock" or die $!; flock($fh, LOCK_EX | LOCK_NB) or do { warn "another instance running\n"; exit 0 }; # ... work ... # lock auto-released when $fh is closed / program exits ``` Classic mailbox appender. Note the [`seek`](seek) to `SEEK_END` after locking — on very old systems `>>` append mode is not atomic, so the write position must be re-established once the lock is held: ```perl use Fcntl qw(:flock SEEK_END); sub lock_mbox { flock($_[0], LOCK_EX) or die "lock: $!" } sub unlock_mbox { flock($_[0], LOCK_UN) or die "unlock: $!" } open my $mbox, ">>", "/var/mail/$ENV{USER}" or die $!; lock_mbox($mbox); seek($mbox, 0, SEEK_END) or die "seek: $!"; print $mbox $msg, "\n\n"; unlock_mbox($mbox); close $mbox; ``` Shared read lock while loading a config file, letting other readers proceed concurrently: ```perl use Fcntl qw(:flock); open my $fh, "<", "config.dat" or die $!; flock($fh, LOCK_SH) or die "lock: $!"; my @lines = <$fh>; close $fh; # releases the lock ``` Upgrading a shared lock to exclusive — the second `flock` atomically swaps modes: ```perl flock($fh, LOCK_SH) or die $!; # ... inspect contents ... flock($fh, LOCK_EX) or die $!; # now we intend to write ``` ## Edge cases - **Locks are per-filehandle, not per-file**. Two independent opens of the same path each have their own lock slot. This is why locking your own file twice from the same process through different handles can deadlock or behave surprisingly on `fcntl(2)`-based systems. - **Closing the filehandle releases the lock.** There is no separate "unlock" step required at program exit; `LOCK_UN` is useful only when you want to keep the handle open after. - **`LOCK_NB` failure is not a croak.** It returns false and sets [`$!`](../perlvar) to `EWOULDBLOCK`. Treat it as an expected outcome, not an error. - **Advisory only.** A process that never calls `flock` sees no locks. Use `flock` as a cooperation protocol among your own programs, not as a security mechanism. - **Whole files only.** There is no byte-range locking through `flock`. For record-level locking use [`fcntl`](fcntl) with `F_SETLK` / `F_SETLKW`. - **NFS and other network filesystems.** Some older NFS implementations cannot honour `flock` across hosts; the call may silently become a no-op or return success without providing exclusion. Use [`fcntl`](fcntl) locking if network coordination matters. - **Fork inheritance.** When the platform uses real `flock(2)` (Linux does), locks are inherited across [`fork`](fork); the child shares them with the parent. On `fcntl(2)`-emulated platforms locks do not survive the fork, which makes writing locking servers considerably harder. - **Buffer flushing.** Perl flushes `FILEHANDLE`'s output buffer on every `flock` call. Code that mixes buffered [`print`](print) with locking does not need an explicit flush before the lock boundary. - **Interaction with `dup`-style opens.** An open of the form `open(my $A, ">>&=", $B)` shares the underlying file descriptor with `$B`, so `flock($A)` and `flock($B)` act on the same lock slot. A `>>&` dup gives each handle its own descriptor and its own lock slot. ## Differences from upstream Fully compatible with upstream Perl 5.42. pperl runs on Linux only, where `flock(2)` is always available, so the "platform has no locking primitive — fatal error" path documented upstream never triggers in practice. ## See also - [`fcntl`](fcntl) — byte-range and advisory locking with finer control; use it when whole-file granularity is too coarse or when network filesystems require it - [`open`](open) — produces the filehandle `flock` operates on; remember that the required open mode (`<` vs `>`) matters for `fcntl`-emulated `LOCK_SH` / `LOCK_EX` - [`close`](close) — releases any `flock` still held on the handle - [`seek`](seek) — pair with `flock` when appending to files that other processes may have extended while you waited for the lock - [`fork`](fork) — lock inheritance across child processes depends on the underlying locking primitive - [`Fcntl`](../../Fcntl) — source of the `LOCK_SH`, `LOCK_EX`, `LOCK_UN`, `LOCK_NB` constants and the `:flock` import tag