in reply to Should I use threads? Perl/DHCP/Radius

BrowserUK, I have gone through several of your posts here and also perldocs / google. Apparently, references or notes on Perl threads concurrency and how to safely handle events after the thread has been completed is rarely dealt with. I do understand that this will take several pages or even a whole book. But I think for people new to threads, it would be a eye-opener!
  • Comment on Re: Should I use threads? Perl/DHCP/Radius

Replies are listed 'Best First'.
Re^2: Should I use threads? Perl/DHCP/Radius
by BrowserUk (Patriarch) on Aug 24, 2010 at 14:38 UTC
    how to safely handle events after the thread has been completed

    If you would describe the complete application, it would be far easier to suggest a good approach. What may work well for one type of application, or even appear correct for some partial description; may prove less good once the full picture is available,

      Please refer to the code you suggested and my OP.

      I constantly read /var/log/messages for DHCPACK. When I find one, I parse the MAC and send the API request in a separate thread. The creation of the threads is not a problem. The issue is how can I bring back the result as quickly as possible back to the main process.

      Example: I get 10 such DHCP requests in less than 1 second. My code luanches all the threads in less than a second. . But bringing back the threads into the main process is causing delays with the logic below/

      The rough logic here:
      for(;;){ while ( <DHCP> ) { # New ACK found. # $macthreads{$mac} = new thread(\&launch, l_opts) }#while foreach $mac (keys(%macthreads)){ if($macthreads{$mac}->is_joinable { $macthreads{$mac}->join; delete $macthreads{$mac}; } }#for

      I used the Time::HiRes module. The first thread completes in 1 second. The last in more than 8 seconds.

        I would use Threads::Queue to send messages back from your threads to your main thread instead of polling them for becoming ->joinable.

        For passing thread results back otherwise, see threads, which documents the return value of ->join(). I would avoid using that, because to get more speed, you will want to keep a pool of worker threads and pass the queries to them using another Thread::Queue instead, thus saving the cost of creating and destroying a new thread for every request.

        Hm. Why do you want to get the results back in the main thread? What are you going to do with them there, that you couldn't do with it in the thread where you obtained them?

        You've set up your main thread to read (follow?) this logfile. That's a nicely defined, and self regulating division of labour. What makes it necessary to confuse that by requiring it to also check for and do something with the results?

        Any information that is available to the "main" thread (which is just another thread after all), is (or can be) available to each of the checking threads you spawn. So what stops them being able to complete the processing required for the MAC they were given?

        Of course, there are occasions where it is required, or just easier, to perform some final processing on the results from different threads in a common place. But there is still no need to confuse the log reading thread by trying to multiplex this workload in there. Simply start another thread to take care of it.

        Or, if it makes sense that this final processing take place in the "main" thread, spawn another thread at the beginning of the program to do the reading from the file. That way your "main" thread can concentrate upon the final processing.

        And so I come back to the same questions I asked earlier. Can you post a high level overview of the processing requirements of the application? It would make it much easier to suggest a good solution.


        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".
        In the absence of evidence, opinion is indistinguishable from prejudice.