There several models how to do many tasks simultaneously in single app: event loop, threads, fork... Let's take event loop and fork. Is it has sense to use both in single app?

At a glance - yes, of course! Event loop require event handlers doesn't take too much time to execute, because while one handler working all other events waiting. And first solution which come in mind - fork long-running event handler in separate process.

But let's check this in deep...

For ex. app has a lot of installed timers, needed for different things. And it does fork. So, what should happens with these timers in child process? Is child should inherit all timers? Or clear all timers? Or inherit only some timers? Huh...

Usually, when we do fork in usual, linear app, we know app state at that point, and know how we should change it state after fork (close some FD, clear some signals, etc.). But in event loop-based app we usually don't know current app state good enough to do such things.

All code in event loop-based app usually in event handlers. So, fork also will be executed inside event handler. After return in child process - what code will be executed? Ok, let's do not return - but what about die/exceptions?

One more example. We use events to monitor some FD in epoll. Then we do fork. At first, child inherit epoll's FD, used to control epoll. At second, it inherit all FD used in parent process. At this point parent may start receiving unexpected and strange epoll events, because of several reasons.

Actually this question has nothing with perl, it's much more general.

I've tested Event and Event::Lib - both do nothing to handle fork, and even doesn't mention issues related to fork in documentation.

Perl6 will contain event loop in core... and I doesn't see how it can work around these issues.

Or... there no issues here at all, and I just misunderstand some concepts?

Replies are listed 'Best First'.
Re: Event-based app and fork()
by perrin (Chancellor) on Dec 04, 2007 at 16:54 UTC
    Take a look at the POE modules that use forking to handle things that don't have a non-blocking API.
Re: Event-based app and fork()
by locked_user sundialsvc4 (Abbot) on Dec 04, 2007 at 13:17 UTC

    Yes, “it makes sense to use both fork and poll,” but I'm not sure that I would do it quite in the way you seem to be contemplating.

    Let the main thread (so to speak) do the polling, and let it do all of it. Then, when a piece of work has arrived in that way, it can queue it up and let it be processed by one of the "forks" .. the threads .. which sit around waiting for something to arrive in one of the queues they are listening to. The threads don't “poll.”

    Notice also that I'm suggesting that the threads don't die off. They stick around, even if at the moment they have nothing to do.

    The main-thread is the switchboard operator. Who is, of course, also the boss.

      Let the main thread (so to speak) ... let it be processed by one of the "forks" .. the threads .... The threads don't “poll.”

      So which are you suggesting to use? Forking or threads?

      Because whilst the OPs question seems very clear to me:"Let's take event loop and fork."; I find your reply very unclear.


      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'm using "forking" and "threads," for my purposes, interchangeably. They're not, but.

        The concept that I'm expressing is like you see in any burger-joint. A few people are sitting there in the front waiting for “connections,” which they immediately punch-into the order system. All the rest of the workers are waiting for requests to pop-up on their queues, and when they do, the workers respond. (Your order has been split and sent to everyone's screen at the same time depending on what you order... if the computer is actually working. :-) When the order is finished, the person who took the order hands your burger to you.

        So you have:   one thread that's handling the select-polling; and one or more threads which the work and have nothing to do with polling at all.

          A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Event-based app and fork()
by powerman (Friar) on Dec 06, 2007 at 20:40 UTC
    Looks like I've found one CPAN module which is aware about this issue and trying to solve it in some way: EV.
Re: Event-based app and fork()
by reenen (Acolyte) on Jan 07, 2011 at 16:19 UTC

    For Event, the child will inherit the timers. This is not a problem though since you do not want the child to return control back to Event.

    So at the end of the work done in the child, you exit. You can unloop before or after the child does its work too ... though I agree it does not seem clear from the Event docs what this buys you or whether it is preferred.

    If you 'return' at the end of the child, with no unlooping, you end up with 2 event loops running and the same configured watchers. If you unloop, you continue from after where you called Event::loop.

    Some code to illustrate the idea:

    1 #!/usr/bin/perl 2 3 use strict; 4 use warnings; 5 6 use Event; 7 use POSIX ":sys_wait_h"; 8 9 Event->signal(signal=>'CHLD', cb=>sub{ 10 my $kid; 11 do { 12 $kid = waitpid(-1, WNOHANG); 13 } while ($kid > 0); 14 }); 15 16 Event->timer(after=>1, interval=>2, cb=>sub { 17 print "$$: timer\n"; 18 my $pid = fork(); 19 return unless (defined($pid)); 20 return if ($pid); 21 22 print "child: $$\n"; 23 `sleep 5`; 24 exit(); # you can also call Event::unloop here. 25 26 }); 27 28 Event::loop(); 29 print "Unloop resumes code here\n";