NAME

POSIX::RT::Semaphore - Perl interface to POSIX.1b semaphores

SYNOPSIS

use POSIX::RT::Semaphore;
use Fcntl;            # O_CREAT, O_EXCL for named semaphore creation

## unnamed semaphore, initial value 1
$sem = POSIX::RT::Semaphore->init(0, 1);

## named semaphore, initial value 1
$nsem = POSIX::RT::Semaphore->open("/mysem", O_CREAT, 0660, 1);

## method synopsis

$sem->wait;                             # down (P) operation
... protected section ...
$sem->post;                             # up (V) operation

if ($sem->trywait) {                    # non-blocking wait (trydown)
  ... protected section ...
  $sem->post;
}

$sem->timedwait(time() + 10);           # wait up to 10 seconds

DESCRIPTION

POSIX::RT::Semaphore provides an object-oriented Perl interface to POSIX.1b Realtime semaphores, as supported by your system. A POSIX semaphore (herein: psem) is a high-performance, persistent synchronization device.

Unnamed psems are typically used for synchronization between the threads of a single process, or between a set of related processes which have inherited the psem from a common ancestor. Named psems are typically used for interprocess synchronization, but may also serve interthreaded designs.

CLASS METHODS

Unless otherwise specified, all methods return the undefined value on failure (setting $!), and a true value on success.

init PSHARED, VALUE

A convenience for the POSIX::RT::Semaphore::Unnamed->init class method.

Return a new POSIX::RT::Semaphore::Unnamed object, initialized to VALUE. If PSHARED is non-zero, the psem may be shared between processes (subject to implementation CAVEATS, below).

Unnamed semaphores persist until explicitly released by calling their destroy method.

open NAME
open NAME, OFLAGS
open NAME, OFLAGS, MODE
open NAME, OFLAGS, MODE, VALUE

A convenience for the POSIX::RT::Semaphore::Named->open class method.

Return a new POSIX::RT::Semaphore::Named object, referring to the underlying semaphore NAME. Other processes may attempt to access the same psem by that NAME.

OFLAGS may specify O_CREAT and O_EXCL, imported from the Fcntl module, to create a new system semaphore. A filesystem-like MODE, defaulting to 0666, and an initial VALUE, defaulting to 1, may be supplied.

Named semaphores persist until explicitly removed by a call to the unlink class method. A subsequent open of that NAME will return a new system psem.

Remove the named semaphore identified by NAME. Analogous to unlinking a file on UNIX-like systems, removal does not invalidate psems already held open by other processes.

SEMAPHORE OBJECT METHODS

Common Methods

getvalue

Return the current value of the semaphore, or, if the value is zero, a negative number whose absolute value is the number of currently waiting processes.

name

Return the object's associated name as set by "open", or undef if created by "init". Deprecated for unnamed psems.

post

Atomically increment the semaphore, allowing waiters to proceed if the new counter value is greater than zero.

timedwait ABSOLUTE_TIMEOUT

Attempt atomically to decrement the semaphore, waiting until ABSOLUTE_TIMEOUT before failing.

$sem->timedwait(time() + .5);  # wait half a second
trywait

Atomically decrement the semaphore, failing immediately if the counter is at or below zero.

wait

Atomically decrement the semaphore, blocking indefinitely until successful.

POSIX::RT::Semaphore::Unnamed Methods

destroy

Invalidate the underlying semaphore. Subsequent method calls on the psem will simply croak. Operations on a destroyed psem by another process, one which has inherited the now-defunct semaphore, for example, are undefined.

This method may fail if any processes is blocked on the underlying semaphore.

Note that this is distinct from Perl's DESTROY.

POSIX::RT::Semaphore::Named Methods

close

Close the named semaphore for the calling process; subsequent method calls on the object will simply croak. The underlying psem, however, is not removed until a call to POSIX::RT::Semaphore->unlink(), nor does the call to close affect any other process' connection to the same semaphore.

This method is called implicitly when the last object representing a particular semaphore in a process is DESTROYed.

CONSTANTS

POSIX::RT::Semaphore offers a number of constants for import:

SEM_NSEMS_MAX, _SC_SEM_NSEMS_MAX

The maximum number of semaphores, per-process. This number is actually _POSIX_SEM_NSEMS_MAX, and the _SC constant may be passed to POSIX::sysconf() to determine the process' true current limit.

SEM_VALUE_MAX, _SC_SEM_VALUE_MAX

The highest value a semaphore may have. This number is actually _POSIX_SEM_VALUE_MAX, and the _SC constant may be passed to POSIX::sysconf() to determine the process' true, current ceiling.

SIZEOF_SEM_T

The size of a sem_t object on your system.

Your system may define other constants for import, such as SEM_NAME_LEN or SEM_NAME_MAX (each the maximum length of a named semaphore's name).

CAVEATS

PERSISTENCE

POSIX semaphores are system constructs existing apart from the processes that use them. For named psems in particular, this means that the value of a newly opened semaphore may not be that VALUE specified in the "open" call.

Depending on the application, it may be advisable to "unlink" psems before opening them, or to specify O_EXCL, to avoid opening a pre-existing psem.

ENOSYS AND WORSE

Implementation details vary, to put it mildly. Consult your system documentation.

Some systems support named but not anonymous semaphores, others the opposite, and still others are somewhere in between. "timedwait" may not be implemented (failing with $! set to ENOSYS). "getvalue" is much more widely supported, though its special negative semantics may not be.

More subtly, "init" with a non-zero PSHARED may succeed, but the resultant psem might be copied across processes if it was not allocated in shared memory. On systems supporting mmap(), POSIX::RT::Semaphore initializes psems in anonymous, shared memory to avoid this unpleasantness.

Semaphore name semantics is implementation defined, making portable name selection difficult. POSIX conservatives will use only pathname-like names with a single, leading slash and no other slashes (e.g., "/my_sem"). However, at least the OSF/Digital/Tru64 implementation currently maps names directly to the filesystem, encouraging semaphores such as "/tmp/my_sem". On at least some FreeBSD implementations, semaphore pathnames may be no longer than 14 characters.

MISC

wait/post are known by many names: down/up, acquire/release, P/V, and lock/unlock to name a few.

TODO

Extend init() to support user-supplied, shared memory objects.

SEE ALSO

IPC::Semaphore, Thread::Semaphore

AUTHOR

Michael J. Pomraning

Please report bugs via rt.cpan.org.

COPYRIGHT AND LICENSE

Copyright 2009 by Michael J. Pomraning

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.