shmget#
Create or look up a System V shared memory segment and return its identifier.
shmget is the allocation step for SysV shared memory. Given a
numeric KEY (either IPC_PRIVATE for a fresh anonymous segment or
a well-known number agreed with other processes), a requested SIZE
in bytes, and a bit-mask of FLAGS (creation flags OR’d with a
9-bit mode), it returns a kernel-assigned integer identifier. That
identifier — the shmid — is what every subsequent call
(shmctl, shmread, shmwrite)
uses to refer to the segment. The segment persists in the kernel
until it is explicitly removed with shmctl($shmid, IPC_RMID, 0)
or the system reboots; closing the creating process does not
release it.
Synopsis#
shmget KEY, SIZE, FLAGS
What you get back#
An integer shared-memory identifier (shmid) on success, suitable
for passing to shmctl, shmread, and
shmwrite. On failure returns a false value and sets
$! to the underlying errno.
use IPC::SysV qw(IPC_PRIVATE IPC_CREAT S_IRUSR S_IWUSR);
my $shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT | S_IRUSR | S_IWUSR)
or die "shmget: $!";
The returned identifier is an opaque small integer. Do not do
arithmetic on it, do not compare it to 0 for truth — the identifier
0 is a legitimate value on some systems. Always check the return
against the documented failure sentinel (see Differences from
upstream).
Global state it touches#
$!— set on failure to the underlyingerrno:EACCES(permissions),EEXIST(segment for that key already exists and bothIPC_CREATandIPC_EXCLwere given),EINVAL(SIZEbelowSHMMINor aboveSHMMAX, orSIZEdiffers from the existing segment when looking one up),ENFILE/ENOSPC(kernel segment-table full),ENOENT(no segment for that key andIPC_CREATwas not given),ENOMEM(insufficient memory).
The function is otherwise pure with respect to Perl-visible state:
no special variables beyond $! are touched,
$_ is not read.
Examples#
Create a fresh private segment — the usual pattern when parent and
children share memory via fork:
use IPC::SysV qw(IPC_PRIVATE IPC_CREAT S_IRUSR S_IWUSR);
my $size = 4096;
my $shmid = shmget(IPC_PRIVATE, $size, IPC_CREAT | S_IRUSR | S_IWUSR)
or die "shmget: $!";
# children inherit $shmid across fork and attach via shmread/shmwrite
Attach to a pre-existing segment by its well-known key. SIZE and
mode bits are ignored in this form; pass 0 for both:
my $key = 0xDEADBEEF;
my $shmid = shmget($key, 0, 0)
or die "shmget: $!";
Create-or-open with IPC_CREAT. If the key already exists the
existing shmid is returned; otherwise a new segment of SIZE
bytes is created with the given mode:
use IPC::SysV qw(IPC_CREAT S_IRUSR S_IWUSR S_IRGRP);
my $shmid = shmget(0x1234, 8192, IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP)
or die "shmget: $!";
Fail if a segment already exists, using IPC_EXCL. This is the
safe pattern for a process that wants to be the unique creator:
use IPC::SysV qw(IPC_CREAT IPC_EXCL S_IRUSR S_IWUSR);
use Errno qw(EEXIST);
my $shmid = shmget(0x1234, 4096, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
if (!$shmid) {
die "shmget: $!" unless $! == EEXIST;
# another process won the race; fall back to plain lookup
$shmid = shmget(0x1234, 0, 0) or die "shmget (lookup): $!";
}
Full create-use-destroy cycle with guaranteed cleanup via END:
use IPC::SysV qw(IPC_PRIVATE IPC_CREAT IPC_RMID S_IRUSR S_IWUSR);
my $shmid = shmget(IPC_PRIVATE, 1024, IPC_CREAT | S_IRUSR | S_IWUSR)
or die "shmget: $!";
END {
shmctl($shmid, IPC_RMID, 0) if defined $shmid;
}
shmwrite($shmid, "hello", 0, 5) or die "shmwrite: $!";
shmread($shmid, my $buf, 0, 5) or die "shmread: $!";
Edge cases#
use IPC::SysVis effectively mandatory. The flag constants (IPC_PRIVATE,IPC_CREAT,IPC_EXCL,IPC_RMID) and mode bits (S_IRUSR,S_IWUSR,S_IRGRP, …) are not built-ins. Without the import you end up passing bare barewords that stringify to0and silently do the wrong thing.Key
0is notIPC_PRIVATE.IPC_PRIVATEis defined as0on Linux, but passing a literal0with noIPC_CREATasks the kernel for the segment at key0, which is theIPC_PRIVATEsentinel and yieldsEINVAL. Import the constant by name and use it.SIZEis rounded up to a page boundary by the kernel; the returned segment may be larger than requested. Ask the kernel for the effective size withshmctl($shmid, IPC_STAT, $ds)and unpack theshmid_dsstructure if you need the real number.Segment persists beyond process exit. A crashed or killed creator leaves the segment in the kernel. Use
ipcs -mto list orphaned segments andipcrm -m <shmid>to remove them. Install anENDblock or a signal handler to callshmctl IPC_RMIDon shutdown.IPC_RMIDis deferred, not immediate. It marks the segment for destruction; actual removal happens once the attach count drops to zero. Safe to call right aftershmgetif you know no one else will attach.Kernel limits.
SHMMNIcaps the total number of segments system-wide (/proc/sys/kernel/shmmni).SHMMAXcaps the size of one segment (/proc/sys/kernel/shmmax). On a shared host these are easy to hit; treatENOSPCandEINVAL-from-large-size as configuration issues, not bugs.SysV IPC is not available on every platform. Upstream Perl built on a system without
HAS_SHMdies with"System V IPC is not implemented on this machine". pperl targets Linux only, where SysV IPC is always present, so the call is always dispatched.
Differences from upstream#
Returns
-1rather thanundefon failure. Both values are false under Perl’s truth rules, so the idiomaticshmget(...) or die "$!"works unchanged, but code that distinguishes “not an identifier” viadefined $shmidwill read-1as defined. Prefer checking for truth, or compare against-1explicitly when you want to branch on the failure sentinel. The-1is the rawshmget(2)return value, which is the documented error sentinel for that syscall.
See also#
shmctl— control operations on the segmentshmgetreturned; useIPC_RMIDto delete it,IPC_STATto inspect size and permissionsshmread— readSIZEbytes from the segment into a Perl scalarshmwrite— write a Perl scalar into the segment at an offsetmsgget— the equivalent allocation step for SysV message queues when you want a queue, not a flat buffersemget— the equivalent for SysV semaphores when the goal is synchronisation rather than shared dataIPC::SysV— source of theIPC_*andS_*flag constantsshmgetrequires; no local reference page, see upstream POD