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

In a recent thread about starting detached processes on Windows using the special form system(1,...), I got a recommendation to use Win32::Job instead of system(1,...), as this would be safer to use and easy too. So I started to play around with Win32::Job, basically trying this:

... my $j=Win32::Job->new; $j->spawn('perl.exe', "perl.exe myprog.pl", { new_console=>0, new_group=>1, stderr=> $out, stdout=> $out }) unlink 'killfile.txt'; $j->watch(sub { -e 'killfile.txt' ? 1 : 0 }, 3); print "go on\n"; ...
The purpose of watch() is to abort the spawned program and all child processes it might have been created, prematurely if the file killfile.txt gets created.

This works indeed, but there is one big difference compared to when I implement the same using system(1,...):

With system(1,...), I get a separate process, i.e. my Perl program continues to run. With Win32::Job, the watch call blocks, i.e. "go on" is printed only after "perl.exe myprog.pl" has (forcefully or gracefully) finished; so Win32::Job doesn't seem to be an alternative for system(1,...), but simply something different.

Of course I could combine the two approaches: Write a helper script 'spawn_and_watch.pl', which I would start with system(1,...), and which does the spawn and watch calls; but I have somehow the feeling that there should be an easier solution. Did I miss something here?
-- 
Ronald Fischer <ynnor@mm.st>

Replies are listed 'Best First'.
Re: Win32::Job::watch vs. system(1,...)
by BrowserUk (Patriarch) on Sep 24, 2009 at 16:38 UTC

    What creates 'killfile.txt'?


    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.
      What creates 'killfile.txt'?
      A separate process, so this is not something we have to worry in this context.

      -- 
      Ronald Fischer <ynnor@mm.st>

        Let's see if I got this right.

        1. You have one process that starts a second asynchronous process (that may start other child processes).
        2. And once it has started that first process, you want it to both watch for the creation of a killfile (produced by yet another asynchronous process).
        3. And at the same time, be able to continue doing other things concurrently with watching for this kill file so that it can kill the process tree it started.

        I guess the author would say: I didn't design the watch method for that scenario.


        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: Win32::Job::watch vs. system(1,...)
by Anonymous Monk on Sep 24, 2009 at 14:26 UTC
    Did I miss something here?

    Yes. Someone has to watch, system 1... never watched, unless you spawned, I mean system 1... a watcher program.

      Someone has to watch, system 1... never watched
      With system 1, I can implement the watching by myself. My main focus was not so much, how to implement the "watch" logic, but to find an easy way to create a separate process (or thread), which can later be killed in a way that killing the process would automatically kill its childs. My first approach was to use system 1 for creating the process, and then remembering the PID, and later using kill -9 to kill this process.

      When discussing this solution, BrowserUk suggested using Win32::Job instead. I was only vaguely famimilar with this module and new that I can use it to control a process in a way that I can kill a whole process tree (the childs of the process) easily, so I thought that maybe there is also some feature in Win32::Job which would do the spawning. It seems that I was wrong with this. Or I stay with my original solution of sticking with system 1 only and kill the process with -9 (negative kill signal also means to kill the process group, but I have yet to find out whether this really always works reliably on Windows).

      So the safest way would probably be to spawn a separate process (using system 1, and within this process use Win32::Job to spawn my application and control it using watch.
      -- 
      Ronald Fischer <ynnor@mm.st>