Yes that works. Unintuatively, an unshared array of references to shared scalars does the trick:
#! perl -slw use strict; use threads qw[ yield ]; use threads::shared; sub thread { my $tid = threads->tid; my $refSem = shift; while( 1 ) { warn( "$tid: locking sem\n" ); lock( $$refSem ); warn( "$tid: waiting sem\n" ); cond_wait( $$refSem ); print "$tid: got: $$refSem"; warn( "$tid: yielding\n" ); yield; warn( "$tid: looping\n" ); } } our $T ||= 2; my @sems = map{ my $var :shared; \$var } 0 .. $T; my @threads = map{ threads->create( \&thread, $sems[ $_ ] ); } 1 .. $T; while( 1 ) { my $value = int( rand 1000 ); my $thread = 1 + int rand( $T ); my $refSem = $sems[ $thread ]; warn( "0: locking sem for thread $thread\n" ); lock( $$refSem ); warn( "0: Setting sem[ $thread ] to $value\n" ); $$refSem = $value; warn( "0: signalling sem[ $thread ]\n" ); cond_signal( $$refSem ); warn( "0: Sleeping\n" ); yield; }
Shame there isn't a less clumsy way to allocate an array of shared scalars than:
my @sems = map{ my $var :shared; \$var } 0 .. $T;
It's also high time that the "documented limitation" (BUG!):
share() allows you to share($hashref->{key}) without giving any error message. But the $hashref->{key} is not shared, causing the error "locking can only be used on shared values" to occur when you attempt to lock($hasref->{key}).
that also affects array elements was fixed.
In reply to Re^2: How to create a collection of shared scalars suitable for locking and signalling?
by BrowserUk
in thread How to create a collection of shared scalars suitable for locking and signalling?
by BrowserUk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |