MCE::Shared::Condvar - Condvar helper class
This document describes MCE::Shared::Condvar version 1.699_013
use MCE::Shared; my $cv = MCE::Shared->condvar( 0 ); # oo interface $val = $cv->set( $val ); $val = $cv->get(); $len = $cv->len(); # conditional locking primitives $cv->lock(); $cv->unlock(); $cv->broadcast(); $cv->broadcast(0.05); # delay before broadcasting $cv->signal(); $cv->signal(0.05); # delay before signaling $cv->timedwait(2.5); $cv->wait(); # sugar methods without having to call set/get explicitly $val = $cv->append( $string ); # $val .= $string $val = $cv->decr(); # --$val $val = $cv->decrby( $number ); # $val -= $number $val = $cv->getdecr(); # $val-- $val = $cv->getincr(); # $val++ $val = $cv->incr(); # ++$val $val = $cv->incrby( $number ); # $val += $number $old = $cv->getset( $new ); # $o = $v, $v = $n, $o
This helper class for MCE::Shared provides a Scalar, Mutex, and primitives for conditional locking.
Scalar
Mutex
The following demonstrates barrier synchronization.
use MCE; use MCE::Shared; use Time::HiRes qw(usleep); my $num_workers = 8; my $count = MCE::Shared->condvar(0); my $state = MCE::Shared->scalar("ready"); my $microsecs = ($^O eq "cygwin") ? 0 : 200; # The lock is released upon calling ->broadcast, ->signal, ->timedwait, # or ->wait. For performance reasons, the variable is *not* re-locked # after the call. Therefore, re-lock the variable for synchronization # afterwards if necessary. sub barrier_sync { usleep($microsecs) until $state->get eq "ready" or $state->get eq "up"; $count->lock; $state->set("up"), $count->incr; if ($count->get == $num_workers) { $count->decr, $state->set("down"); $count->broadcast; } else { $count->wait while $state->get eq "up"; $count->lock; $count->decr; $state->set("ready") if $count->get == 0; $count->unlock; } } # Time taken from a 2.6 GHz machine running Mac OS X. # If you want a fast barrier synchronization, let me know. # I can add MCE::Shared::Barrier to behave like MCE Sync. # # threads::shared: 0.238s threads # forks::shared: 36.426s child processes # MCE::Shared: 0.397s child processes # MCE Sync: 0.062s child processes sub user_func { my $id = MCE->wid; for (1 .. 400) { MCE->print("$_: $id\n"); # MCE->sync(); # via MCE Core API barrier_sync(); # via MCE::Shared::Condvar } } my $mce = MCE->new( max_workers => $num_workers, user_func => \&user_func )->run;
Constructs a new condition variable. Its value defaults to 0 when value is not specified.
0
value
# shared use MCE::Shared; $cv = MCE::Shared->condvar( 100 ); $cv = MCE::Shared->condvar;
Sets the value associated with the cv object. The new value is returned in scalar context.
cv
$val = $cv->set( 10 ); $cv->set( 10 );
Returns the value associated with the cv object.
$val = $cv->get;
Returns the length of the value. It returns the undef value if the value is not defined.
undef
$len = $var->len;
Attempts to grab the lock and waits if not available. Multiple calls to $cv-lock> by the same process or thread is safe. The mutex will remain locked until $cv-unlock> is called.
$cv-
$cv->lock;
Releases the lock. A held lock by an exiting process or thread is released automatically.
$cv->unlock;
Releases a held lock on the variable. Then, unblocks one process or thread that's waiting on that variable. The variable is *not* locked upon return.
wait
Optionally, delay floating_seconds before signaling.
floating_seconds
$count->signal; $count->signal( 0.5 );
The broadcast method works similarly to signal. It releases a held lock on the variable. Then, unblocks all the processes or threads that are blocked in a condition wait on the variable, rather than only one. The variable is *not* locked upon return.
broadcast
signal
Optionally, delay floating_seconds before broadcasting.
$count->broadcast; $count->broadcast( 0.5 );
Releases a held lock on the variable. Then, waits until another thread does a signal or broadcast for the same variable. The variable is *not* locked upon return.
$count->wait() while $state->get() eq "bar";
Releases a held lock on the variable. Then, waits until another thread does a signal or broadcast for the same variable or if the timeout exceeds floating_seconds.
A false value is returned if the timeout is reached, and a true value otherwise. In either case, the variable is *not* locked upon return.
$count->timedwait( 10 ) while $state->get() eq "foo";
This module is equipped with sugar methods to not have to call set and get explicitly. The API resembles a subset of the Redis primitives http://redis.io/commands#strings without the key argument.
set
get
Appends a value at the end of the current value and returns its new length.
$len = $cv->append( "foo" );
Decrements the value by one and returns its new value.
$num = $cv->decr;
Decrements the value by the given number and returns its new value.
$num = $cv->decrby( 2 );
Decrements the value by one and returns its old value.
$old = $cv->getdecr;
Increments the value by one and returns its old value.
$old = $cv->getincr;
Sets the value and returns its old value.
$old = $cv->getset( "baz" );
Increments the value by one and returns its new value.
$num = $cv->incr;
Increments the value by the given number and returns its new value.
$num = $cv->incrby( 2 );
The conditional locking aspect is inspired by threads::shared.
Perl must have the IO::FDPass module installed for constructing a shared queue or condvar while the shared-manager process is running.
queue
condvar
For platforms where IO::FDPass is not feasible, construct queues or condvars first before other classes. The shared-manager process is delayed until sharing other classes or explicitly starting the process.
IO::FDPass
queues
condvars
use MCE::Shared; my $q1 = MCE::Shared->queue(); my $cv = MCE::Shared->condvar(); MCE::Shared->start();
MCE, MCE::Core, MCE::Shared
Mario E. Roy, <marioeroy AT gmail DOT com>
To install MCE, copy and paste the appropriate command in to your terminal.
cpanm
cpanm MCE
CPAN shell
perl -MCPAN -e shell install MCE
For more information on module installation, please visit the detailed CPAN module installation guide.