my $lock : shared; { lock($lock) ...do something that only 1 thread at a time should do... } #### use threads; use threads::shared; use Thread::Queue; my $max_threads = 8; my $queue = Thread::Queue->new(); print "Spawning threads..."; for(1...$max_threads){ threads->create(\&thread_main)->detach(); } print "Done!\n"; ...Do what you need to do to get a work unit... $queue->enqueue("SOME_WORK_UNIT"); #Signal to the threads they're done. for(1...$max_threads){ $queue->enqueue("DONE"); } wait_on_threads(); exit 0; sub thread_main(){ while(1){ my ($work) = $queue->dequeue()); # If end-of-queue marker reached then cleanup and exit. if($app eq "DONE"){ return 0; } ...do processing work... } } sub wait_on_threads(){ #Dont even start printing messages until our queue is near depleted. while($queue->pending() > $max_threads){ sleep 1; } my $cnt = 0; my $wait = 5; while(my $items = $queue->pending() > 0){ # Fortunatly on AIX sleep doesnt seem to put ALL the threads to sleep. # whew! This is a non-portable loop though ;) if ($cnt++ > $wait){ print "Please wait. $items items still in progress.\n"; $cnt = 0; $wait++; } sleep 3; } }