bigbot has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks, I had a question about implementing an output queue from multiple threads, using Thread::Queue. It's "working" without warnings or errors, but the memory usage gets way out of control, and it's also a lot slower than using locks and shared variables (which I assume it cause I screwed something up). I understand the memory usage would go up if the output queue was getting more than it could handle. In any case I can't seem to find many examples so any advice would be appreciated.

The reason I wanted to use an output queue is that the worker queue is processing very large files on different computers (so it made sense to use threads). The output needs to be serialized. Previously I used a lock as I said. I heard that using an output queue would be better design. So I want to pass the output from the worker threads to the output queue and print the data there.

sub runSearch { my $outputQueue = Thread::Queue->new(); my $outputThread = threads->create(\&outputSub,$outputQueue); my $workerQueue = Thread::Queue->new(); my @workerThreads = map threads->create(\&workerSub,$workerQueue,$ou +tputQueue), 1..$numThreads; $workerQueue->engueue($_) foreach @computer; $workerQueue->enqueue(undef) for 1..$numThreads; $outputQueue->enqueue(undef); $_->join for @workerThreads; $outputThread->join; } sub workerSub { my ($workerQueue,$outputQueue) = @_; while (my $computer = $workerQueue->dequeue()) { ## SSH command retrieving grep results and processing $outputQueue->enqueue($results); } } sub outputSub { my $outputQueue = $_; while (my $packet = $outputQueue->dequeue()) { print $results; } }

Replies are listed 'Best First'.
Re: Output Queue from Multiple Threads
by BrowserUk (Patriarch) on Jul 31, 2015 at 14:09 UTC

    The simplest solution to the memory growth problem is to bound the size of the queue in the writers:

    use constant LIMIT => 1000; sub pause { my $delay = shift; select '','','', $delay; } sub workerSub { my ($workerQueue,$outputQueue) = @_; while (my $computer = $workerQueue->dequeue()) { ## SSH command retrieving grep results and processing pause( 0.01 ) while $outputQueue->pending > LIMIT; $outputQueue->enqueue($results); } }

    For a slightly more sophisticated approach, take a look at my self-limiting queue implementation:threads::Q


    Anyone got any experience of this phone's predecessor?

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
    I'm with torvalds on this Agile (and TDD) debunked I told'em LLVM was the way to go. But did they listen!
      OK great thanks Browser, I see your posts all the time and they are a huge help with threads! So aside from that you don't see any obvious issues with that example?
        So aside from that you don't see any obvious issues with that example?

        This looks suspect to me: $outputQueue->enqueue(undef); If the intent of the undef is to terminate the output sub loop, pushing it before the output has been queued ain't gonna work.

        And this: $workerQueue->engueue($_) foreach @computer; tells me you haven't run the code you posted; so ...


        Anyone got any experience of this phone's predecessor?

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
        In the absence of evidence, opinion is indistinguishable from prejudice.
        I'm with torvalds on this Agile (and TDD) debunked I told'em LLVM was the way to go. But did they listen!
Re: Output Queue from Multiple Threads
by bigbot (Beadle) on Jul 31, 2015 at 16:05 UTC
    I should also point out that the version of Perl isn't exactly new (5.8.8), and furthermore it's using Thread::Queue 2.00. Some of the options on the CPAN page don't even exist, so I'm not sure if that could be causing some issues as well.
    A reply falls below the community's threshold of quality. You may see it by logging in.
A reply falls below the community's threshold of quality. You may see it by logging in.