shmwrite#
Copy bytes into a System V shared memory segment.
shmwrite attaches to the shared memory segment identified by ID,
copies up to SIZE bytes from STRING starting at byte offset POS
inside the segment, and detaches. If STRING is longer than SIZE,
only the first SIZE bytes are written; if it is shorter, the
remainder of the SIZE-byte window is zero-filled with NUL bytes. The
segment ID is the value returned by an earlier shmget
call (or obtained from another process via some out-of-band channel).
Synopsis#
shmwrite ID, STRING, POS, SIZE
What you get back#
True on success, false on error, with $! set to the
reason (typically EINVAL, EACCES, or EIDRM). Unlike most I/O
built-ins the return value is a plain boolean — there is no byte-count
variant, because the count is always exactly SIZE when the call
succeeds.
shmwrite($id, $payload, 0, 4096)
or die "shmwrite($id) failed: $!";
Global state it touches#
Examples#
Publish a fixed-size record at the start of a segment:
use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR);
my $id = shmget(IPC_PRIVATE, 4096, S_IRUSR | S_IWUSR)
or die "shmget: $!";
shmwrite($id, "hello, world", 0, 4096)
or die "shmwrite: $!";
A STRING shorter than SIZE is NUL-padded to fill the window —
useful for clearing stale trailing bytes from a previous writer:
shmwrite($id, "short", 0, 64); # 5 bytes of "short", then 59 NULs
A STRING longer than SIZE is truncated; the tail is silently
discarded, so size your window to the largest record you ever intend
to publish:
shmwrite($id, "x" x 10_000, 0, 128); # only the first 128 x's land
Writing to a non-zero offset lets multiple fixed-size records share one
segment. Pair it with a matching shmread on the reader
side:
my $slot = 3;
my $len = 64;
shmwrite($id, $record, $slot * $len, $len)
or die "shmwrite slot $slot: $!";
Check the return value — a segment that has been marked for deletion
with IPC_RMID continues to accept writes from processes already
attached, but fails for new shmwrite calls with EIDRM:
unless (shmwrite($id, $msg, 0, $SIZE)) {
warn "segment $id gone: $!";
# reacquire via shmget() and retry
}
Edge cases#
Kernel must be built with SysV IPC. On systems without SysV shared memory
shmwritecroaks withshmwrite not implemented. This is a compile-time property of the kernel / libc, not a runtime condition you can probe for.SIZEof0is accepted by the kernel and writes nothing;shmwritereturns true. Use it only when you genuinely mean “no-op”, not as an error signal.POS + SIZEmust fit inside the segment. Overrunning the segment boundary fails withEINVALand leaves the segment untouched — the copy is not partial.Binary payloads are fine.
STRINGis treated as a byte string; embedded NULs are written literally. If the string carries the UTF-8 flag, the raw internal bytes are what hits the segment — usepackorEncode::encodefirst if you need a specific encoding on the wire.No locking. The kernel guarantees that each
shmwritecall is atomic with respect toshmat/shmdt, but two concurrent writers can still interleave byte ranges within the segment. Coordinate withsemopor a user-space lock if multiple processes write the same region.Permissions come from the segment’s mode at
shmgettime. Attaching read-only and callingshmwritefails withEACCES.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
shmread— inverse operation; copy bytes out of a segment into a Perl scalarshmget— obtain theIDthatshmwritewrites intoshmctl— inspect segment attributes, change permissions, or mark a segment for deletionsemop— the usual companion primitive for serialising access to a shared segmentpack— build the fixed-layout byte string you hand toshmwritewhen the segment holds structured recordsIPC::SysV— constants (IPC_PRIVATE,S_IRUSR,IPC_RMID) used to construct the arguments toshmgetandshmctl