Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

code executed at end of a thread

by dk (Chaplain)
on Dec 04, 2009 at 12:27 UTC ( [id://811070]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks,

I have a problem which I can't resolve so far. The problem goes with that I have a module, that creates some objects for internal use, that are cleared up in END{} block, before the global destruction. Which makes sense, because if it doesn't do so, all kinds of strange errors appear because some scalar A expects a scalar B alive in DESTROY, but B was killed already by global destruction mechaism, etc... So far so good.

But, the very same module doesn't fare well as soon an unrelated code starts to use threads. When that thread ends, it also brings down all copied references from the parent thread, including the internal objects from the said module. But since END{} block is not executed by the end of a thread, global destruction kills these object without an order, and the problems described above reappear.

My question is, is there a mechanism, or a best practice of sorts, how to deal with such situations? I see following possibilities:

* Rewrite module with explicit init() and done() calls. Would solve the problem, but one of main ideas of that module was actually to be transparent and not to require any calls of such kind. Also, if a thread exits with threads->exit it wouldn't help.
* Submit a patch to perl that enables an ENDTHREAD {} or something like that. Possible, but requires a lenghty discussion and release process, and I need a solution now.

Anything I missed? All ideas are welcome. Thanks!

Update: perlfaq8 brings even more confusion with this sentence: 'Each package's END block is called when the program or thread ends'. Well, it doesn't now.

Replies are listed 'Best First'.
Re: code executed at end of a thread
by BrowserUk (Patriarch) on Dec 04, 2009 at 13:00 UTC

    From threads POD:

    END blocks in threads It is possible to add END blocks to threads by using require or eval w +ith the appropriate code. These END blocks will then be executed when the thre +ad's interpreter is destroyed (i.e., either during a ->join() call, or at p +rogram termination). However, calling any the threads manpage methods in such an END block +will most likely fail (e.g., the application may hang, or generate an error) due + to mutexes that are needed to control functionality within the the thread +s manpage module. For this reason, the use of END blocks in threads is strongly discoura +ged.

    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.
      Thank you, that's a good advice. I also found SKIP_CLONE with a description that fits ideally, but perl panicks when I use it :)
Re: code executed at end of a thread
by zentara (Archbishop) on Dec 04, 2009 at 13:06 UTC
    .... any other ideas?.... yes..... a thread needs to return or go to end of it's code block before it can finish..... so i have retreated into the brute force habit of using a GOTO as a way of terminating a thread, where the GOTO label sends execution to a few lines preceeding the threads actual return...... you can do your thread specific cleanup there....but as always....i may be missing the secret design you have :-)

    ...see Reusable threads demo and look at the end of the thread code block..... and it would be good to follow TGI's advice to use cleanly labeled nested loops instead of GOTO's ;-)

    ....i'm an old dog and reserve the right to use a goto every now and then


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku
      That's so far my best guess too - except that my design is that I'm writing a generic library, and don't have a control over what threads do, that's up to the programmers. I'd hate to impose an extra requirement, like "hey use my lib but also use a goto" (I personally don't mind goto at all, and use them too), but you get my drift...

      I thought rather that I missed some obscure language feature, and am trying to reinvent a wheel.

        .... well then, use the nested labeled loops, as i suggested..... that code is just a simple example to illustrate exacting thread control..... running threads on manual so to speak, rather than requireing a thread helper library like a queue......and goto's are such a clean hack, that everyone should have it in their toolkits, even if the bossman dosn't like them :-)

        ....you can start up threads and pass perl code strings to them, thru shared variables, and have them eval'd in the thread.....but then the ugliness of an exit call taking down the whole house of cards raises it's head..... i don't know what you are doing, but threads may not be what you are looking for....unless you are on win32..... bwahaha.... then i can't help

        ....but you may have a bigger design problem with module safety..... hows that for b*llsh*t ;-)


        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (8)
As of 2024-04-23 07:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found