Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Hanging Threads

by WalkingZero (Sexton)
on Aug 18, 2007 at 05:14 UTC ( #633430=perlquestion: print w/ replies, xml ) Need Help??
WalkingZero has asked for the wisdom of the Perl Monks concerning the following question:

Need some help. Currently the program is running 4 separate threads, pulling data off a queue to establish it's given task. The sub runs a while loop based off the queue's pending function. The threads all exit their while loops correctly. However after the sub should be done, the joins never occur. I can't quite figure out what's causing the lockup. Any help would be appreciated. Here's the censored version of the code:

sub smtpblast{ my $mdq= shift; my $pending= $mdq->pending; while($pending>0){ my $md= $mdq->dequeue_nb; my $user= $maildrop{"$md" . "user"}; my $pass= $maildrop{"$md". "pass"}; print "\n $user \n $pass \n"; my $mailer=Net::SMTP_auth->new('****'); $mailer->auth('Login', $user, $pass); $mailer->mail("$user"); $mailer->to('****'); my @data=("Subject: Test Messages from $user\n", "E-mail Blast message + from $user\n"); $mailer->data(@data); $mailer->datasend(); $mailer->dataend; $mailer->quit; $pending= $mdq->pending; } $threadid=threads->self; print "\n The process for thread $threadid is finished!\n"; } my $mdqueue=Thread::Queue->new(); $mdqueue->enqueue("md01", "md02", "md03", "md04", "md05", "md06", "md0 +7", "md08", "md09", "md10"); $thr1=threads->new(\&smtpblast, $mdqueue); $thr2=threads->new(\&smtpblast, $mdqueue); $thr3=threads->new(\&smtpblast, $mdqueue); $thr4=threads->new(\&smtpblast, $mdqueue); $thr1->join; print "\n Thread $thr1 joined! \n"; $thr2->join; print "\n Thread $thr2 joined! \n"; $thr3->join; print "\n Thread $thr3 joined! \n"; $thr4->join; print "\n Thread $thr4 joined! \n";

The program is for testing mail server latency. I have edited out server information and omitted the has that contains the logins. This is all the relevant pieces of code though.

Comment on Hanging Threads
Download Code
Re: Hanging Threads
by GrandFather (Cardinal) on Aug 18, 2007 at 05:38 UTC

    Altering your code to run as a standalone sample without needing access to a mail server and using threads (hence create rather than new) I get:

    use warnings; use strict; use threads; use Thread::Queue; sub smtpblast{ my $mdq= shift; my $pending= $mdq->pending; while ($pending > 0){ my $md= $mdq->dequeue_nb; print "processing $md\n"; sleep $md; $pending= $mdq->pending; } my $threadid = threads->self; print "\n The process for thread $threadid is finished!\n"; } my $mdqueue=Thread::Queue->new(); $mdqueue->enqueue(10, 2, 5, 3, 7, 5); my $thr1=threads->create (\&smtpblast, $mdqueue); my $thr2=threads->create (\&smtpblast, $mdqueue); my $thr3=threads->create (\&smtpblast, $mdqueue); my $thr4=threads->create (\&smtpblast, $mdqueue); $thr1->join; print "\n Thread $thr1 joined! \n"; $thr2->join; print "\n Thread $thr2 joined! \n"; $thr3->join; print "\n Thread $thr3 joined! \n"; $thr4->join; print "\n Thread $thr4 joined! \n";

    which prints:

    processing 10 processing 2 processing 5 processing 3 processing 7 processing 5 The process for thread threads=SCALAR(0x3fdc57c) is finished! The process for thread threads=SCALAR(0x4508800) is finished! The process for thread threads=SCALAR(0x3ab0328) is finished! The process for thread threads=SCALAR(0x2534bbc) is finished! Attempt to free unreferenced scalar: SV 0x2023ed0, Perl interpreter: 0 +x2018414 at C:\Documents and Settings\Peter\My Documents\PerlScratch\ +noname.pl line 22. Thread threads=SCALAR(0x201f7e8) joined! Attempt to free unreferenced scalar: SV 0x22c2318, Perl interpreter: 0 +x22bf014 at C:\Documents and Settings\Peter\My Documents\PerlScratch\ +noname.pl line 23. Thread threads=SCALAR(0x201f7f4) joined! Attempt to free unreferenced scalar: SV 0x383cc50, Perl interpreter: 0 +x3afc294 at C:\Documents and Settings\Peter\My Documents\PerlScratch\ +noname.pl line 24. Thread threads=SCALAR(0x201f800) joined! Attempt to free unreferenced scalar: SV 0x3d68e68, Perl interpreter: 0 +x3d65314 at C:\Documents and Settings\Peter\My Documents\PerlScratch\ +noname.pl line 25. Thread threads=SCALAR(0x201f80c) joined!

    and terminates as expected despite the errors.

    Can you generate a similar sample the demonstrates the problem you are seeing?


    DWIM is Perl's answer to Gödel

      FYI: new() is an alias for create() in threads.

      Also, I don't see any of the unreferenced scalar errors when I run the OPs code?

      Update: I don't see the unreferenced scalar errors when I run your version either, so this appears to be a problem with your setup.


      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.
Re: Hanging Threads
by Ninthwave (Chaplain) on Aug 18, 2007 at 05:48 UTC
    Where do you test for the UNDEF that ->dequeue_nb returns when it hits the end of the queue?

    To quote Thread::Queue
    "dequeue_nb The dequeue_nb method, like the dequeue method, removes a scalar from the head of the queue and returns it. Unlike dequeue, though, dequeue_nb won't block if the queue is empty, instead returning undef. "
    "No matter where you go, there you are." BB
      Arg if you read the previous reply ignore it. I need to read more clearly. I am using the Queue's pending function and testing for that in the while loop. Like I said the loop breaks cleanly. it just hangs in the sub though for some reason.
Re: Hanging Threads
by BrowserUk (Pope) on Aug 18, 2007 at 12:06 UTC

    Your code as is, but with the Net::SMTP stuff commented out and replaced by a couple of sleeps, functions perfectly. Ie. The threads start, read the work items off the queue, terminate their loops and exit. And the joins all complete successfully and cleanly. Under 5.8.6 and 5.8.8.

    So, maybe Net::SMTP isn't thread safe? Try starting one thread and see if that completes successfully?

    If one works, try starting 2.

    If you post again, properly indented code would be good.


    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.
      I found the problem(s). My issue kept getting complicated by the fact that the way I'd fix one issue would cause another. Something in my loop structure before was originally causing the issue. So when I used the 'self' function to test for loop exit, it helped me fix my loop. The ->self function though appears to have been what was locking the threads and preventing them from rejoining. Once I removed those two lines, I was golden.
        The ->self function though appears to have been what was locking the threads and preventing them from rejoining.

        Intriguing. Could you try putting those two lines back, but changing

        my $threadid = threads->self:

        to

        my $threadid = threads->self->tid;

        And report back what happens.

        FYI. threads->self() returns the thread's object reference, threads->self->tid() returns the thread's numeric identifier.

        I'm not aware that it would make a difference, but there is the possibility of some kind of circular reference prevent cleanup?

        If the above change 'cures' the problem, it might be a bug worth reporting. That said, I couldn't make it happen in either of the builds I have available. Which version of threads are you using? Eg.

        perl -mthreads -le"print $threads::VERSION" 1.62

        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.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://633430]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (14)
As of 2014-09-01 13:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite cookbook is:










    Results (13 votes), past polls