NAME

IPC::Semaphore::Concurrency - Concurrency guard using semaphores

SYNOPSIS

use IPC::Semaphore::Concurrency;

my $c = IPC::Semaphore::Concurrency->new('/tmp/sem_file');

if ($c->acquire()) {
    print "Do work\n";
} else {
    print "Pass our turn\n";
}


my $c = IPC::Semaphore::Concurrency->new(
    path  => '/tmp/sem_file',
    count => 2,
    value => $sem_max,
    );

if ($c->acquire(0, 1, 0)) {
    print "Do work\n";
} else {
    print "Error: Another process is already locked\n";
}

if ($c->acquire(1)) {
    print "Do other work\n";
}

DESCRIPTION

This module allows you to limit concurrency of specific portions of your code. It can be used to limit resource usage or to give exclusive access to specific resources.

This module is similar in functionality to IPC::Concurrency with the main differences being that is uses SysV Semaphores, and allow queuing up processes while others hold the semaphore. There are other difference which gives more flexibility in some cases.

Generally, errors messages on failures can be retrieved with $!.

EXPORTS

None for now (could change before first Beta)

CONSTRUCTOR

IPC::Semaphore::Concurrency->new( $path );

IPC::Semaphore::Concurrency->new(
    path    => $path
    project => $proj_id
    count   => $sem_count
    value   => $sem_value
    touch   => $touch_path
    );
path

The path to combine with the project id for creating the semaphore key. This file is only used for the inode and device numbers. Will be created if missing.

project

The project_id used for generating the key. If nothing else, the semaphore value can be used as changing the count will force generating a new semaphore. Defaults to 0.

count

Number of semaphores to create. Default is 1.

value

Value assigned to the semaphore at creation time. Default is 1.

touch

If true, tough the path when creating the semaphore. This can be used to ensure a file in /tmp do not get removed because it is too old.

FUNCTIONS

getall

getval

getncnt

id

setall

setval

stat

remove

These functions are wrapper of the same functions in IPC::Semaphore.

For getval and getncnt, if no argument is given the default is 0.

key

$c->key();

Return the key used to create the semaphore.

acquire

$c->acquire();

$c->acquire($sem_number, $wait, $max, $undo);

$c->acquire(
    sem  => $sem_number,
    wait => $wait,
    max  => $max,
    undo => $undo,
    );

Acquire a semaphore lock. Return true if the lock was acquired.

sem

The semaphore number to get. Defaults to 0.

wait

If true, block on semaphore acquisition.

max

If wait is true, don't block if max processes or more are waiting for the semaphore. Defaults to -1 (unlimited).

You may want to set it to some decent value if blocking on the semaphore to ensure processes don't add up infinitely.

undo

If defined and false, the semaphore won't be released automatically when process exits. You must release manually and only once the semaphore with $c->release(). See release for important information before using this!

Use with caution as you can block semaphore slots if the process crash or gets killed.

release

$c->release();

$c->release($sem_number);

WARNING: Use this at your own risks and only after understanding the implications below!

This function is useful only if you turn off the undo option in acquire function and must be used with it. It merely increment the semaphore by one.

In its usual use case, IPC::Semaphore::Concurrency is locked once and until the process exits. This function allow you to control yourself the release of the lock, but you must understand what releasing a semaphore actually means. Semaphores are merely counters and every time you acquire them you merely decrease the value - the locking happens once the counter reaches 0.

This means if you release more than once, you will effectively increase the semaphore value and next time the semaphore is used it will require as many acquire to lock or fail locking. This includes the implicit increase when the process exits when you don't set undo to false in acquire!. This means if you use release without undo set to false, you will raise the value again at every process exit and your semaphore won't lock things anymore!

TODO

Allow setting semaphore permissions, default to 600

Allow private semaphores

Allow passing an array of values

BUGS

semop(3) and semop(3p) man pages both indicate that errno should be set to EAGAIN if the call would block and IPC_NOWAIT is used, yet in my tests under Linux errno was set to EWOULDBLOCK. See example.pl and example2.pl for examples of paranoiac error checking. YMMV.

Please report bugs to tguyot@gmail.com.

SEE ALSO

IPC::Semaphore - The module this is based on.

The code repository is mirrored on http://repo.or.cz/w/IPC-Semaphore-Concurrency.git

CLI tools for controlling semaphores:

ipcs(1), especially ipcs -s for listing all semaphores

ipcrm(1), for removing semaphores by ID (-s) or KEY (-S)

AUTHOR

Thomas Guyot-Sionnest <tguyot@gmail.com>

COPYRIGHT AND LICENSE

Copyright (C) 2009 Thomas Guyot-Sionnest <tguyot@gmail.com>

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available.