NAME Shared::Simple - Inter-process shared memory key-value store SYNOPSIS use Shared::Simple; # First process: create a fresh segment (cleans up any stale leftovers) my $shm = Shared::Simple->new('myapp', Shared::Simple::EXCLUSIVE); # Subsequent processes: attach to the existing segment my $shm = Shared::Simple->new('myapp', Shared::Simple::SHARED); # or simply omit the mode SHARED is the default my $shm = Shared::Simple->new('myapp'); # Store a value $shm->put('greeting', 'hello'); # Retrieve a value my $val = $shm->get('greeting'); # 'hello' # Missing key returns undef my $x = $shm->get('nosuchkey'); # undef DESCRIPTION "Shared::Simple" provides a persistent, named key-value store backed by POSIX shared memory ("shm_open"/"mmap"). Multiple processes can open the same named segment simultaneously; reads and writes are serialised with a process-shared POSIX mutex. The underlying hash table resizes automatically when it runs out of space. METHODS new my $shm = Shared::Simple->new($name); my $shm = Shared::Simple->new($name, $mode); Opens or creates a POSIX shared memory segment identified by $name. $mode controls how an existing segment is handled and must be one of the two constants exported by this module: "Shared::Simple::SHARED" (default) Create-or-attach semantics. If the named segment does not yet exist it is created and initialised; if it already exists the process attaches to it. This is the right mode for every worker that shares data with others. If another process is currently initialising the segment, "new" will wait up to five seconds before croaking with a timeout error. "Shared::Simple::EXCLUSIVE" Fresh-start semantics. Any existing segment with this name is unlinked before the new one is created, guaranteeing a clean, empty hash table. Use this once at program startup -- typically in the parent process before forking -- to ensure a consistent initial state regardless of leftovers from previous runs. See "CAVEATS" for important restrictions. $name must be a non-empty string short enough to form a valid POSIX shared memory name (roughly "NAME_MAX - 1" characters on the target platform). Returns a blessed "Shared::Simple" object. Croaks on failure. put $shm->put($key, $value); Stores $value under $key in the shared segment. If $key already exists its value is overwritten. Constraints: * Both $key and $value must be defined and non-empty strings. * $value must not exceed 32 bytes. Returns 1 on success. Croaks on validation failure or an internal error. get my $value = $shm->get($key); Looks up $key in the shared segment. Returns the stored string on success, or "undef" if the key does not exist. $key must be a defined, non-empty string; otherwise the method croaks. get_size my $n = $shm->get_size; Returns the number of key-value pairs currently stored in the shared segment as an integer. get_all my $href = $shm->get_all; Returns a reference to a Perl hash containing every key-value pair currently stored in the shared segment. The returned hash is a snapshot taken under the lock; it is independent of the shared memory and safe to read or modify after the call returns. CONCURRENCY All operations acquire a process-shared POSIX mutex before touching shared memory. On Linux, the mutex is configured as robust: if a process dies while holding the lock, the next caller will recover it automatically ("EOWNERDEAD" handling). This recovery is not available on macOS. LIMITATIONS * Values are limited to 32 bytes. Storing longer strings will croak. * The shared memory segment persists until it is explicitly unlinked from the filesystem (e.g. with shm_unlink(3)); destroying the Perl object only detaches the mapping. CAVEATS EXCLUSIVE mode is not safe to call concurrently "EXCLUSIVE" unlinks the underlying POSIX shared memory objects and recreates them from scratch. This is an inherently destructive, non-atomic sequence of operations. If two or more processes call "new" with "EXCLUSIVE" for the same name at the same time, they will race to destroy each other's live segment, causing data corruption, invalid internal state, and unpredictable failures in every process sharing that segment. Only one process must ever call "new" with "EXCLUSIVE" for a given name at any one time, and no other process should be attached to the segment when it does so. The intended pattern is: # Parent / coordinator -- runs once before workers start Shared::Simple->new('myapp', Shared::Simple::EXCLUSIVE); # Workers -- fork after the parent has finished initialising for (1 .. $N) { fork or do { my $shm = Shared::Simple->new('myapp', Shared::Simple::SHARED); ...; exit; }; } AUTHOR Denys Fisher, COPYRIGHT AND LICENSE Copyright (C) 2026 by Denys Fisher This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.