Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Unload ithread

by rodd (Beadle)
on Jul 24, 2008 at 17:16 UTC ( #699934=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks,

I'm looking for a way to pause a perl 5.8.8 interpreter thread and later restore it at the same (or next) line in the thread script. And with the same var namespace. By "later" I mean that the perl interpreter may have to be stopped, then restarted next day. So the thread state should be stored in the filesystem.

The reason for this is that I'm working on a perl server daemon that launches threads that do things for users. Now I want to give my users the possibility to "pause" their corresponding thread, go on vacation, and let the thread continue when their are back, without having to worry about server crashes while they're gone.

I've spent the day reading into Data::Dumper and its serializers, PadWalker, __LINE__, eval and goto's, and I think a combination of all these may give me a "homegrown" solution. But it seems quite painful to turn all local and global vars into evalable code, then restore it later and goto to where it stopped. (I have no eval security concerns, as this is all private code).

The sam'ol perl developer dilemma... Am I reinventing the wheel here? Any better packages around cpan to do the job better?

In a perfect world:

use threads; ... sub mythread { ... threads->self->unload("/threadfile.id") if($goaway); ## I'm back. Keep going... } sub laterdaemon { threads->reload("/threadfile.id"); }
cheers
Rod

	The blood red ran from the Grey Monk's side,
	His hands and feet were wounded wide,
	His body bent, his arms and knees
	Like to the roots of ancient trees.
	--William Blake

Replies are listed 'Best First'.
Re: Unload ithread
by BrowserUk (Pope) on Jul 24, 2008 at 17:36 UTC

    I'm quite prepared to be proved wrong on this, but from my perspective this simply cannot be done.

    As for why. There is no way to preserve/restore the state of the cpu registers, and if you can't do that, the rest is irrelevant.


    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.
      In principle CPU registers aren't the biggest problem if the VM supports it somehow (I don't know if perl 5 does continuations internally; if yes, they could be serialized. But somehow I doubt it). Kernel drivers that do suspend-to-disk get around this problem somehow.

      But there are other problems like pipes, sockets, open file handles (for example under Linux you can have an open file handle to an unlinked file - you can't really restore that) and network connections, and you have to think about what you do with $^T, for example.

      All in all I think it's easier to make that particular application serialize its data and dump it to disk, and then resume later on.

        But there are other problems like pipes, sockets, open file handles...

        As they are all process global entities, so long as the process continued running, they would persist, and once the thread was restored, it could continue to use them. All the caveats about changes to them and other process global state like $^T are essentially the same as if the thread had slept, or been suspended.

        Equally, these problems exist with existing mechanisms for suspending (hibernating) processes to disk (think laptops). If anything modifies the state of the filesystem between suspend and resume, things get screwy. If you close you laptop while programs are connected to the net, they probably won't like it much when you try to restore them. Some protocols like http being connectionless, mean that browser can redisplay the cached state of pages and interaction can continue, assuming a new connection has been established. But you'll have less luck with most other protocols.

        Perl 5 doesn't do continuations, or anything close to them. Hence the reason I say the register state is the biggest insurmountable problem.

        In theory, as iThreads are always clones of their 'parent' (notional only), then if you could 'capture' the state of a thread immediately after it is created, but before tranfering control to it, you would have a restorable, known state.

        So, to save the state of a thread, you would have it spawn a new thread--which would be a clone of itself--and then immediately die. The thread procedure for that new thread could then serialise itself to disk and die also.

        The problem then comes at restoration. You spawn a new thread to restore the serialised one from disk, but it will be a clone of it's parent--there's currently no way to avoid that (more's the pity)--so the deserialise thread proc would have to clean itself of inherited state, prior to reconstructing the saved state.

        And that's currently not doable by any stretch of my imagination.


        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: Unload ithread
by zentara (Archbishop) on Jul 24, 2008 at 17:40 UTC
    If you can keep the parent process going, you can use sleeping threads. See Reusable threads demo. Just put your thread into a sleep state. Of course your thread code block must have a convenient place to be interrupted.

    As an afterthought, you might want to look at the shell mechanisms for suspending processes in the background, google for "bash suspend" for the idea.


    I'm not really a human, but I play one on earth Remember How Lucky You Are
Re: Unload ithread
by chrism01 (Friar) on Jul 25, 2008 at 04:50 UTC
    I believe its more a case of designing a thread's work unit in such a way that it is restartable from a known good pt. Think SQL Commit etc.
    Then it needs to save that state to a file and exit. When the restart request comes in, the parent thr starts a new thr and instructs it to read the state file.
    Any pre-reqs depend on whether they are std across all child thrs, in which case that can be coded in to the parent or child, or the child will have to save/extract the prereqs list from the file and performing the relevant actions.

    Cheers
    Chris

Re: Unload ithread
by diotalevi (Canon) on Jul 25, 2008 at 15:59 UTC

    I suppose if you moved to an unthreaded model, you might be able to use cryopid. I don't see any way to freeze and unfreeze a single thread without massive amounts of perl guts hacking.

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (5)
As of 2020-11-28 08:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?