use strict; use warnings; use threads; use Thread::Queue qw( ); my $q = Thread::Queue->new(); my $t1 = async { sub1(); $q->enqueue(1); }; my $t2 = async { sub2(); $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(); push @threads, async { sub5() }, async { sub6() }; --$pending; } if (!$pending) { push @threads, async { sub7() }, async { sub8() }; last; } } $_->join() for @threads;