Andreas Altergott wrote:
Hi,
Andrew Feren wrote:
I removed the calls to exit() and the service started working as
expected. Calling exit() from the child resulting from perl's pseudo
fork is supposed to work (and often does). Unfortunately it has been my
experience that sometimes the results are a catastrophic failure.
That's a surprise. So the exit subroutine must call something
different, than simply letting the program run out. That would be a
nice question to the ActiveState developers.
This is an area that has always bothered me.
The "perlfork" docs state :
/exit()/ always exits just the executing pseudo-process, after
automatically /wait()/-ing for any outstanding child
pseudo-processes. Note that this means that the process as a whole
will not exit unless all running pseudo-processes have exited.
This makes sense since the goal, as I understand it, is to as much as
possible have fork() code just work on Windows. For many examples it does.
Perl threads started life as a way to implement "perlfork". OK, so far
so good. However, if we read the "threads" documentation we find :
*exit(status)*
Calling exit EXPR <http://perldoc.perl.org/functions/exit.html>
inside a thread causes the whole application to terminate. Because
of this, the use of |exit()| inside threaded code, or in modules
that might be used in threaded applications, is strongly discouraged.
If |exit()| really is needed, then consider using the following:
1. threads->exit() if threads->can('exit'); # Thread friendly
2. exit(status);
Clearly pseudo-processes (aka threads ;) are intended to do the right
thing relative to exit (and with good reason). However, the foundation
they are built on is very exit() averse.
There is the possibility to use fork() as long as you do not use exit()
then. Probably that's why threads have been working. I did not use
exit() there.
You *really* don't want to call exit() if you are using threads directly.
I'm just curious. Is there another way to stop a POE application
immediately?
The answer depends a little on your intent. If you really want to
terminate an application inclusive all threads exit() works great (as
long as you don't need to do any cleanup ;). If you just want to
terminate a single thread try threads->exit() (if it is available).
After tripping over problems with exit() a couple times I just take care
to have a code path that will quietly run out of things to do without
calling exit() explicitly.
There's the possibility of using stop(). If I run this inside the
forked child, this should not affect the parent. But still some code in
the _stop state will get executed.
How did you use exec()? calling exec() after the fork() failed for me
in the same way as calling exit.
I did not try to run exec() from a fork. That's sad to hear, else one
could use Wheel::Run by setting the program to an array. This would run
exec() on line 443, instead of the final exit() on line 440 in Wheel::Run.
yep. That was what I thought too, but no luck.
IMO death by exit() in a pseudo-process is a bug, but it isn't clear if
the bug is in the "perlfork" implementation my code or some
combination. I did notice that Win32::Daemon starts several threads.
From the outside looking in I can't tell if they are pseudo-processes
or threads, but I'd guess they are threads. Which brings me to this
quote from the perl thread tutorial.
"Thinking of mixing |fork()| and threads? Please lie down and wait
until the feeling passes."
I think, from the rest of the context, that this quote is referring to a
real UNIX fork() and not "perlfork", but then again...
I wonder if calling exit from a pseudo-process would kill off threads
that happen to be running and aren't also pseudo processes.
-Andrew