use threads; use threads::shared; use constant NUM_WORKERS => ...; sub process { my ($node) = @_; ... } { my $tree: shared = ...; my $q = Thread::Queue->new(NUM_WORKERS); for (1..NUM_WORKERS) { async { while (my $node = $q->dequeue()) { process($node); } }; } my @todo = $tree; while (@todo) { my $node = pop(@todo); $q->enqueue($node); push @todo, $node->children(); } $q->end(); $_->join() for threads->list(); }