semget#
Create or look up a System V semaphore set and return its identifier.
semget is the entry point into the SysV semaphore API. It wraps the
semget(2) system call: given a numeric KEY that names the set, the
number of semaphores NSEMS in the set, and a FLAGS word combining
permission bits with creation flags, the kernel either returns the id
of a matching existing set or, if IPC_CREAT is in FLAGS, creates a
new set and returns its id. The returned id is the handle every other
semaphore call (semop, semctl) expects.
Synopsis#
semget KEY, NSEMS, FLAGS
What you get back#
The semaphore set identifier (a non-negative integer) on success, or
undef on failure with $! set to the errno from the
underlying semget(2) call. The id is not a file descriptor —
it is a kernel-wide SysV IPC handle that outlives your process and
persists until explicitly removed with semctl($id, 0, IPC_RMID, 0).
use IPC::SysV qw(IPC_CREAT IPC_PRIVATE);
my $semid = semget(IPC_PRIVATE, 3, IPC_CREAT | 0600)
// die "semget: $!";
Global state it touches#
$!— set to theerrnovalue fromsemget(2)on failure (EACCES,EEXIST,ENOENT,ENOSPC,EINVAL,ENOMEM).
The KEY argument#
KEY is an integer that names the semaphore set system-wide. Three
conventions matter:
IPC_PRIVATE(imported fromIPC::SysV) — the kernel allocates a fresh key unused by any other set. The resulting id is known only to this process and anyone it passes the id to, typically children afterfork. Use this when the set is an implementation detail of one process tree.A fixed integer literal — every cooperating process hard-codes the same number. Fragile across unrelated programs that might pick the same integer.
A key derived from
ftok(3)—IPC::SysV::ftok($path, $proj_id)turns a filesystem path plus a project byte into a numeric key. The standard recipe for unrelated processes that need to agree on a key without hard-coding a magic number.
The FLAGS argument#
FLAGS combines permission bits (low 9 bits, like a chmod mode:
0600, 0660, 0666) with creation flags from IPC::SysV:
IPC_CREAT— create the set if it does not already exist. Without this flag,semgetonly looks up an existing set with the given key.IPC_CREAT | IPC_EXCL— create the set, but fail withEEXISTif one already exists forKEY. The SysV analogue ofO_CREAT | O_EXCLinopen.
Permission bits are checked by the kernel on every subsequent
semop and semctl call against the invoking
process’s uid/gid.
Examples#
Create a private set of three semaphores usable by this process and its children:
use IPC::SysV qw(IPC_PRIVATE IPC_CREAT);
my $semid = semget(IPC_PRIVATE, 3, IPC_CREAT | 0600)
// die "semget: $!";
Look up an existing, named set without creating it. NSEMS must match
the size the set was created with, or can be 0 if you do not care:
use IPC::SysV qw(ftok);
my $key = ftok("/var/run/myapp.pid", ord('M'));
my $semid = semget($key, 0, 0) // die "no set for key $key: $!";
Create-or-open idiom — try exclusive create, fall back to lookup. The first process through initialises the set; later ones just attach:
use IPC::SysV qw(ftok IPC_CREAT IPC_EXCL);
my $key = ftok("/var/run/myapp.pid", ord('M'));
my $semid = semget($key, 4, IPC_CREAT | IPC_EXCL | 0660);
if (defined $semid) {
# We created it — initialise every semaphore to 1.
semctl($semid, 0, SETALL, pack("s!*", (1) x 4))
or die "SETALL: $!";
} else {
$semid = semget($key, 4, 0) // die "semget lookup: $!";
}
Remove a set when you are done with it. SysV sets leak across process exit — nothing cleans them up for you:
use IPC::SysV qw(IPC_RMID);
semctl($semid, 0, IPC_RMID, 0) or warn "semctl RMID: $!";
Edge cases#
NSEMSon lookup: when looking up an existing set (noIPC_CREAT),NSEMSof0means “any size”; a positive value must be less than or equal to the set’s actual size orsemgetfails withEINVAL.IPC_PRIVATEstill obeysFLAGS: permission bits apply. A set created with0400is read-only even to the creating process forsemopcalls that modify it.Kernel limits:
semgetcan fail withENOSPCwhen the system-wide semaphore-set limit is reached, orEINVALwhenNSEMSexceeds the per-set maximum. Seeipcs -slfor the current limits on Linux.Leaked sets: a set persists until
IPC_RMIDor reboot. Long- running daemons that forget to remove their sets accumulate them;ipcs -slists the survivors,ipcrm -s $idremoves one.Key collisions: two unrelated programs picking the same hard- coded
KEYwill see each other’s set — hence theftok(3)idiom.Not a filehandle:
$semidis an integer, not a handle. Do not pass it toclose,fcntl, or any filehandle operation.Forks inherit ids, not ownership: a child sees the same
$semidvalue as the parent and can use it, but the set itself is owned by the uid that created it, not by any particular process.Numeric context: the id is a plain integer, safe to print, compare, and store in a file for another process to pick up.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
semop— perform wait/signal operations on the set returned bysemgetsemctl— control operations on the set: initialise values (SETALL,SETVAL), read them (GETALL,GETVAL), and remove the set (IPC_RMID)msgget— the message-queue counterpart, sameKEY, FLAGSconventionsshmget— the shared-memory counterpart, sameKEY, FLAGSconventionsIPC::SysV— importsIPC_CREAT,IPC_EXCL,IPC_PRIVATE,IPC_RMID,SETALL,GETALL, and theftokhelperIPC::Semaphore— object wrapper around the rawsem*built-ins when you would rather not pack structs by hand