Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

creative forking (code)

by deprecated (Priest)
on Nov 04, 2001 at 02:39 UTC ( #123102=perlquestion: print w/replies, xml ) Need Help??

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

I've got a rather large (~1000 lines) program that runs continually. However, it is "event driven" and doesnt actually do anything until it getts a specific kind of input, or I prod it in some fashion. I have lately been wanting to include a sort of "memo" or "reminder" function into it.

I figure it would require forking off a sub that wasnt event driven. In other words, a specific event would drive a fork in the middle of a sub that was _not_ event driven, like so:

sub non_event_driven { if (fork()) { # i'm the parent! return 1; } else { # i'm the child! for (;;) if (time() == $waiting_epoch) { # ta-da! play an mp3 and wake up our user # or whatever exit 0; # safe for shell, and we're done anyways } } } return 0; }
the problem is, since fork() creates a _copy_ of the program youre running, and your current program is 50mb in memory, you could *seriously* hurt the host machine if you had, say, twenty of them running... as I might well do with a reminder sub.

any suggestions?

brother dep

Laziness, Impatience, Hubris, and Generosity.

Replies are listed 'Best First'.
Re: creative forking (code)
by chromatic (Archbishop) on Nov 04, 2001 at 04:04 UTC
    Memory's not your problem with that code. CPU time is. You have a very tight loop that doesn't relinquish control. If you don't need millisecond precision (and if you're not using an RTOS, it's not guaranteed anyway), throw in a sleep call. You might also appease the style police with a while loop, but do what you like there.

    Memory probably isn't a problem, because Unixy operating systems use copy-on-write techniques when forking a kid. That's why fork is so fast -- the cloned process actually uses the same memory pages as the parent. Only when the kid changes (or writes to) a page is a fresh page allocated. If your hypothetical 50 megabyte program only changes a couple of variables in the kid process, only a couple of pages (probably 4 kilobytes in size on a 32-bit machine) will be unshared.

    Of course, you could write a dedicated program to handle events, perhaps with POE or Schedule::Cron, and have it listen on a pipe for events to schedule.

      ++ chromatic
Re: creative forking (code)
by Fastolfe (Vicar) on Nov 04, 2001 at 03:09 UTC
    Generally if I have a monolithic process that I'm using to watch for events on a filehandle *and* handle timed events simultaneously, I'll just build that into the process's event loop:
    sub event_loop { my $next_event = &get_next_event; # e.g. time() + 5 if (select($rh, $wh, $eh, $next_event - time())) { &process($rh, $wh, $eh); } elsif ($next_event <= time()) { &do_timed_events; } } &event_loop while $running;
    If you're using a forking model, you may need to provide some additional information. Is each child process dedicated to handling one specific timed event, or do you have an existing pool of forked processes doing their own thing, and you just don't care if one of them handles the timed event?

    If you have one or more children that are guaranteed to be running, just assign out your timed event to the first child:

    if (fork()) { $children_spawned++; return 1; } else { # Here, the *very first* child won't have $children_spawned unless ($children_spawned) { print "I'm the first!\n"; &do_main_with_timed_event_processing; } else { &do_main_without_timed_events; } }
    If that first process isn't guaranteed to be running, you may just need some inter-process communication between your children. Whoever steps up to the plate first to handle a timed event gets it. This can be done with shared memory or semaphores. See perlipc for more information.
Re: creative forking (code)
by data64 (Chaplain) on Nov 04, 2001 at 04:18 UTC

    How about using exec in the child process ? Then the child process can be running a separate, smaller script which would take up less memory.

Re: creative forking (code)
by edebill (Scribe) on Nov 04, 2001 at 09:32 UTC
    I've had good luck registering a handler for SIGALRM and setting an alarm to go off. like so:
    $SIG{ALRM} = \&mp3_player; alarm(1);

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2023-06-01 08:15 GMT
Find Nodes?
    Voting Booth?

    No recent polls found