use threads; use threads::shared; my @file_list :shared = @ARGV; my $num_workers = 2; my %MSG :shared; sub process { my ($file) = @_; print "Opening $file\n"; if(some condition){ lock(%MSG); #write stuff to hash } print "Closing $file\n"; } for (1..$num_workers) { async { for (;;) { my $file = do { lock @file_list; return if !@file_list; shift(@file_list) }; process($file); } } } $_->join() for threads::list();