package obj;
use 5.010;
use strict;
use threads;
use Thread::Queue qw( );
sub new {
my ( $class, %args ) = @_;
my $self = bless( {}, $class );
say "creating new obj";
return $self;
}
sub sub1 { say "sub1 starts"; sleep 1 for 1 .. 2; say "sub1 ends" }
sub sub2 {
my $self = shift;
$self->{KEY} = 1;
exists( $self->{KEY} ) ? say "KEY exists" : say "KEY does NOT exis
+t";
say "sub2 starts";
sleep 1 for 1 .. 2;
say "sub2 ends";
}
sub sub3 { say "sub3 starts"; sleep 1 for 1 .. 5; say "sub3 ends" }
sub sub4 { say "sub4 starts"; sleep 1 for 1 .. 5; say "sub4 ends" }
sub sub5 { say "sub5 starts"; sleep 1 for 1 .. 5; say "sub5 ends" }
sub sub6 { say "sub6 starts"; sleep 1 for 1 .. 5; say "sub6 ends" }
sub sub7 { say "sub7 starts"; sleep 1 for 1 .. 2; say "sub7 ends" }
sub sub8 { say "sub8 starts"; sleep 1 for 1 .. 2; say "sub8 ends" }
sub run {
my $self = shift;
my $q = Thread::Queue->new();
my $t1 = async { sub1(); $q->enqueue(1); };
my $t2 = async { sub2($self); $q->enqueue(2); };
my $pending = 2;
my @threads;
for ( ; ; ) {
my $id = $q->dequeue();
if ( $id == 1 ) {
$t1->join();
push @threads, async { sub3() }, async { sub4() };
--$pending;
}
elsif ( $id == 2 ) {
$t2->join();
exists( $self->{KEY} )
? say "KEY exists"
: say "KEY does NOT exist";
push @threads, async { sub5() }, async { sub6() };
--$pending;
}
if ( !$pending ) {
push @threads, async { sub7() }, async { sub8() };
last;
}
}
$_->join() for @threads;
}
1;
test.pl: use strict;
use warnings;
use obj;
my $o = obj->new();
$o->run();
|