|
Hi! I was not sure about the 'scope' of a lock. So I wrote a little test program which might be usefull for others too. You can try to change the behaviour by un-/commenting the two marked locks and the cond_wait(). (If someone wants to add it anywhere, please feel free to do so.) I think there is something not really clear in the documentation for 'lock VARIABLE' in 'perldoc threads::shared': It is sufficient to have ONE lock within ONE thread, to own the shared variable as long as this lock is within the scope of the thread. This lock is kind of inheritet by any called sub function and it does not make a difference if the subfunction does an additional lock or not. (I would rather say, the subfunctions should not do additional locking if the shared variable is already locked.) I do not understand why this behaviour is called 'recursive' in the documentation. I would rather say: "As long as the first lock of one thread is someway within scope, it is active. And it does not make a difference, if this thread puts additional locks on the same variable. (Nor does the thread itself block, because the variable is already locked by this thread)" I hope this may help others too. - Now I will try to rework signalling with my scheduler and worker threads. :-) Comments are welcome, Stefan |
#!/opt/perl_5.8.2/bin/perl -w use threads; use threads::shared;
sub recurse ($$); # prototype (needed because of recursion???)
sub recurse ($$) {
my ($shr, $count) = @_;
if (not --$count) {
# ATTENTION: no explicit lock for the shared variable here!
# you may also comment the following cond_wait() !!!
print"no more locking - doing cond_wait\n"; $|=1;
cond_wait($$shr);
print"no more locking - return in 2 seconds\n"; $|=1;
sleep 2;
return;
}
print"($count) locking\n"; $|=1;
# un-/comment the next line to see the difference
#lock $$shr;
print"($count) sleeping 1\n"; $|=1;
sleep 1;
print"($count) calling myself\n"; $|=1;
recurse ($shr, $count);
print"($count) call done\n"; $|=1;
return;
}
sub th ($) {
my $s = shift;
die"got undefined value" if not defined ($s);
print"thread trying to lock '$s'\n"; $|=1;
lock $$s; # that is the shared variable (reference)
print"thread locked it\n"; $|=1;
sleep 10;
cond_signal $$s;
print"thread terminating\n"; $|=1;
1;
}
print "main\n"; $|=1;
my $share : shared = 0;
my $th;
{
# un-/comment the next line to see the difference
lock $share;
$th = threads->create(\&th, \$share);
print "starting\n"; $|=1;
recurse(\$share, 3);
print "done\n"; $|=1;
}
$th->join; # clean up
