AnyEvent::Fork clarification
Vikas N Kumar
vikas at vikaskumar.org
Sat Jan 11 15:06:18 CET 2014
On 01/11/2014 04:41 AM, Marc Lehmann wrote:
>
> As for zombies, unless you force it, AnyEvent::Fork will only fork one
> process, which then sets SIGCHLD to IGNORE. all other processes are then
> forked from this process (which itself does not exit), so it should be
> quite hard to get any zombies. The zombies are children of which process?
When I run the "ps x" command I see that my forked executables are
listed as <defunct> on completion. They are under the process tree of
"AnyEvent::Fork/exec process of $PID" where $PID is the PID of the
program that launched the AnyEvent::Fork.
I perform an AnyEvent::Fork->new and save that object and then fork from
that object multiple times using the AnyEvent::Fork::fork() method. I
believe the object that I save is the first fork object and that when
cleared up removes all the other defunct processes. So it is not a
problem in the end but just wanted to figure out how to avoid it. This
is why I had to delete this object in the end. I keep it around so that
if I have say more tasks to run than CPUs available, I want to be able
to launch 1 task as soon as 1 CPU becomes available, until all tasks
are complete. This allows my program to maximize CPU resources by
reacting to how tasks finish over time and giving more work to the CPU
that is doing the work faster thus taking care of the case where
multiple CPUs might be on different machines and have different
capabilities.
I tried closing the file handles on EOF receipt but when I close a file
handle and launch another process, perl tries to reuse the file handle.
And then there are errors that say file handle was already closed, which
was weird !
I only remove the watcher on the file handle instead that I was using to
track if the forked child completed or not, as after some playing around
I just couldn't figure out why an EOF was sent on a file handle, which I
then assumed as the child exited and closed it would have something else
be sent on it.
> That condvar->recv works probably indicates yet another error in POE -
> apparently, you probably still need POE to take over the process. What
> happens when you do something like:
>
> POE::Kernel->run;
>
> instead of run Prima? That would run POE as main event loop, which might
> fix things (anyevent shouldn't worry either way).
I will try this and see. When I run my Forker class and handling objects
etc using AnyEvent;:Fork & POE::Loop without Prima stuff works fine. So
I don't think POE is the problem. The problem is "run Prima" not doing
something properly. There is POE::Loop::Prima which I have installed and
maybe that is buggy.
> Not good. The only thing AnyEvent::Fork relies on is I/O watchers.
>
> I guess the right thing to do would be to write an anyevent backend
> for Prima. I don't remember what my problems were when I attempted this long
> ago, I think I just couldn't get Prima to work for me.
>
This is possible. When I get time I can try it.
>>> - the GUI is able to fork if AnyEvent->condvar->recv is called on the
>>> button click but this causes the processes to complete but hang around
>>> as zombies unless the whole GUI process exits.
>> I had to just delete the AnyEvent::Fork object which I was storing in a
>> hash to access from elsewhere. Once this deletion is done, I can
>> recreate it later and it still works.
> Interesting - AnyEvent::Fork literally does no cleaning up whatsoever (it
> doesn't even have a destructor and after the run callback is invoked it will
> clear @$self), so all that would clean up is an empty blessed array.
>
> Maybe you die in the callback somewhere and your event loop silently ignores
> that? That would skip the cleanup and would cause the fork object to keep
> references to the file handle and watcher.
>
> On the other hand, the fork object is useless once run is called, so
> getting rid of that is the way to go.
>
More information about the anyevent
mailing list