Jambo Hamon has asked for the wisdom of the Perl Monks concerning the following question:
#!/usr/bin/perl =begin I interpret the calls of the sub spin below as ``promises''. The spin sub calls "enter" which guarantees that the block will run, but inside that block now we call spin again, which has to guaran +tee that another block will run... Shades of indiffernce might wash over your f +ace, but take a look! It's cool. El Capitano, Jambo Hamon P.S In the context of the last post this is the first ``bit''. P.P.S Si =cut use strict; use warnings; use v5.20; # oh yeah use Time::HiRes qw(usleep); use Data::Dumper; use constant ITER => 200; use constant RAND_SLEEP => 200; use Mutex; my $red = Mutex->new; my $yellow = Mutex->new; my $green = Mutex->new; $red->lock; $yellow->lock; $green->lock; sub spin { # Mutex, subroutine reference, ...Jazz return shift->enter( shift, @_ ); } my $pid = fork; my %t; $t{starttime} = time; # stats data hash symbold lookup .. what scope is this in onc +e we fork? die "$!: who knows me?" if not defined $pid; if ( $pid == 0 ) { #child: fork1 say "fork1 here: $$"; my $pid = fork; die "$!: who knows me?" if not defined $pid; my $cnt; # what scope does $cnt get thrown into... if there onl +y were.. if ( $pid == 0 ) { #child: fork2 say "fork2 here: $$"; # sleep 1; while ( $cnt++ < ITER ) { # usleep int(rand(10)); spin( $red, sub { #say "fork2\\ waiting yellow"; spin( $yellow, sub { say "fork2: red yellow"; $t{fork2}->{r}++; $t{fork2}->{ry}++; $t{fork2}->{y}++; usleep int( rand(RAND_SLEEP) ); } ); } ); spin( $red, sub { spin( $green, sub { say "fork2: red green"; $t{fork2}->{r}++; $t{fork2}->{rg}++; $t{fork2}->{g}++; usleep int( rand(RAND_SLEEP) ); } ); } ); } } else { # fork1 # sleep 2; while ( $cnt++ < ITER ) { # usleep int(rand(5)); spin( $red, sub { # say "fork1\\ waiting green"; spin( $green, sub { say "fork1: red green"; $t{fork1}->{r}++; $t{fork1}->{rg}++; $t{fork1}->{g}++; usleep int( rand(RAND_SLEEP) ); } ); } ); spin( $red, sub { spin( $yellow, sub { say "fork1: red yellow"; $t{fork1}->{r}++; $t{fork1}->{ry}++; $t{fork1}->{y}++; usleep int( rand(RAND_SLEEP) ); # not nece +ssary but thoughtful } ); } ); } wait; } } else { #mothersbaugh ship my $cnt; # sleep works wonders # sleep 2; while ( $cnt++ < 1 ) { # no one can get red, cos it's locked until i unlock it. PID bas +ed switch. # only true on the first iteration. spin( $red, sub { spin( $green, sub { spin( $yellow, sub { say "mothersbaugh: red green yellow"; sleep 1; $t{mothersbaugh}->{r}++; $t{mothersbaugh}->{rg}++; $t{mothersbaugh}->{g}++; $t{mothersbaugh}->{gy}++; $t{mothersbaugh}->{rgy}++; # aw shg +ucks usleep int( rand(RAND_SLEEP) ); # no +t necessary but thoughtful } ); } ); } ); # you can have similar loops here: # now race for red, then wait for yellow # spin($red, sub { #say "mother\\ waiting yellow"; # spin($yellow, sub {say "mother: red yellow"; usleep int(ra +nd(10));} ) }); #now race for red, then wait for green # spin($red, sub { #say "mother\\ waiting green"; # spin($green, sub {say "mother: red green"; usleep in +t(rand(10));} ) }); } wait; } END { # Let the GLOBBLING BEGIN print Dumper( \%t ); }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Why won't this Deadlock?
by marioroy (Prior) on Jul 11, 2017 at 06:07 UTC | |
by Jambo Hamon (Novice) on Jul 11, 2017 at 15:51 UTC | |
by marioroy (Prior) on Jul 11, 2017 at 16:33 UTC | |
|
Re: Why won't this Deadlock?
by Marshall (Canon) on Jul 11, 2017 at 05:48 UTC | |
by Jambo Hamon (Novice) on Jul 11, 2017 at 15:56 UTC | |
by marioroy (Prior) on Jul 12, 2017 at 00:57 UTC | |
by Jambo Hamon (Novice) on Jul 12, 2017 at 01:28 UTC | |
by marioroy (Prior) on Jul 12, 2017 at 04:08 UTC | |
| |
by Jambo Hamon (Novice) on Jul 12, 2017 at 02:08 UTC | |
|