my $NUM_THREADS = 5; my $BUFFER_SIZE = 1; my @inQueues = (); my @threads = (); my $outQ = Thread::Queue->new(); my $readyQ = Thread::Queue->new(); # create worker threads for ( my $i = 0; $i < $NUM_THREADS; $i++ ) { my $inQ = Thread::Queue->new(); my $thr = threads->create( sub { # see the Worker Threads section for this ... } ); push @inQueues, $inQ; push @threads, $thr; # start the threads $readyQ->enqueue( $i ); } # create writer thread my $curLot = 0; my $curBatch = 0; my $curPart = 0; my $writerThr = threads->create( sub { # see the Writer Thread section for this ... } ); # give a line from SEED_FILE to each thread for ( ;; ) { last if eof( $SEED_FILE ); my $nextThread = $readyQ->dequeue(); chomp( my $fastaComment = <$SEED_FILE> ); chomp( my $readSequence = <$SEED_FILE> ); my %item = ( 'lot' => $curLot, 'batch' => $curBatch, 'part' => $curPart, 'fasta' => $fastaComment, 'read' => $readSequence, ); $inQueues[ $nextThread ]->enqueue( \%item ); # get the next batch/part number $curPart = ($curPart + 1) % $NUM_THREADS; if ( $curPart == 0 ) { ++$curBatch; $curBatch %= $BUFFER_SIZE; } if ( $curPart == 0 && $curBatch == 0 ) { ++$curLot; } } # let threads know that input is done for ( my $i = 0; $i < $NUM_THREADS; $i++ ) { $inQueues[ $i ]->enqueue( undef ); } # wait for threads to finish foreach my $thr ( @threads ) { $thr->join(); } $writerThr->join();