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

Greeting fellow monks, In advanced, please forgive me if this message sounds retarted. I'm a Perl newbie, and came accross this great Perl riddle as I was constructng an AIM bot using the Net::AIM package. For those of you who know how to use Net::AIM, when I get the login information, and call the start() method, no other code excecutes. I did a little research and found out that calling start() initiates an infinite loop that checks the socket. One of the things I wanted to do with this bot is to log it onto multiple Screen Names. Since no other code will excecute after start() is called, I thought AH HA! I'M SMART! and tried to put start() in a seperate thread. I then promptly yelled DAMNIT! (and have since prayed to the Perl Gods to forgive me for such a savage act) when I saw the error in my MS DOS prompt window: "A thread exited before 2 other threads." I thought to myself "what the hell?"(and then prayed for forgiveness yet again).....I did some more research on threads in Perl, and came up with no other information than this: this is a really friggin' annoying error. Maybe the perl gods are punnishing me for my heathen ways. Can any of you monks enlighten me as to what i'm doing wrong? much thanks! ~Brian

Replies are listed 'Best First'.
Re: Threads and Net::AIM
by BrowserUk (Patriarch) on Sep 02, 2003 at 03:15 UTC

    batkins is correct. The error message simply means that you didn't clean up the threads you started when your program terminated. The usual strategy to avoid the message is to retain the thread ids (as returned by the thread->new() call) and then call the join() method on them prior to exiting your program.

    However, in order for you to be able to join your threads, you need to arrange for them to terminate. As the threads module stands now, there is no simple mechanism for killing a thread, so you need to arrange for it to die of its own volition.

    The usual mechanism for doing this is to use a shared variable allocated in your main thread prior to spinning the thread(s) as a flag to tell your threads when to die.

    use strict; use threads; use threads::shared; my $flag : shared = 1; sub thread_code { while( $flag ) { # Do your thread stuff here # but make sure it loops every now and then # so that you will see the flag change } } my @threads = map{ threads->new( \&thread_code ) ; } 1 .. 4; ... # when you get told to finish by the user # or otherwise decide to exit. EXIT{ $flag = 0; # tell the kids its time to go $_->join() for @threads; # Wait for them # and go. }

    All of that said, you appear from your brief description to be trying to use a perl object across threads. This doesn't work!

    It may seem to work okay initially, but it is fraught with problems. Any object allocated prior to you starting your threads will be replicated to each of your threads, but they will be different copies of the object.

    Any attempts made to use a single object from multiple threads is going to at best give you catastrophic failures (Perl itself will segfault), or at worst, result in myriad and ever changing "strange errors" that are very hard to track down.

    This is not to say that you cannot use Net::Aim with threads at all. It just means that you will have to understand the requirements and limitations and use threads properly to do so. At the moment, there are very few good examples of using threads available. Perhaps Things you need to know before programming Perl ithreads this recent post by our resident threads expert would be a good place to start before moving on to perlthrtut.

    You could also do a super search for "use threads" and look at some of the most recent stuff posted here. Ignore anything much before the start of this year as it is likely that it relates to the earlier and now defunct pThreads implementation rather than the new (since 5.8.0. You are using 5.8.x aren't you?) iThreads.

    If your serious about pursuing this, then you should really make sure that you have at least perl 5.8.1 (which is not yet available from AS!) as earlier builds had fairly severe problems with memory leaks under some circumstances.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
    If I understand your problem, I can solve it! Of course, the same can be said for you.

      I really appreciate your input. I found that my proplem was much simpler than cleaning up threads: my main thread was exiting before my worker threads. I wanted my worker threads to keep going, but didn't realize that the main thread was exiting. I since restructured my threads so that they exit in order. Thanks for all the useful info! ~B
Re: Threads and Net::AIM
by batkins (Chaplain) on Sep 02, 2003 at 02:15 UTC
    Your post would sound less "retarded" if you used line breaks. :)

    As far as your question, I'm pretty sure that error is just a warning. Bascially, if the main thread of your program exits and there are still other threads running, perl prints that out to let you know. I'm not sure how to suppress it, but I wouldn't worry too much about it unless it's causing your program to break.


    it says she can do math, but will she recognize 8 / 0?

    We can only hope they've put in those safeguards.

    Worst case scenario: She succeeds in dividing by zero, and suddenly little Tiphany-Amber's bedroom becomes the center of a howling vortex of nonspace, frying the neighborhood with sparkling discharges of zero-point energy.

    - slashdot
      The thread error was causing a break, which is why it was so frigin' annoying. I since have fixed it and thank you guys much for you input. ~B