Hi John,

I'm fairly sure I've got it to work with the lowlevel Win32 API calls at some time a long time ago, but I won't try to resurrect that right now...

However...you don't indicate what level of control of the spawned process you need, if any, so if my options here are not sufficient give us some more detail on such things...

I'm attaching three files. The 'detached.pl' is just a simple program that loops by default 10 times, with a seconds sleep in each loop and printing a simple 'progress counter' before it exits with exitcode 42 (to just demonstrate capturing that in my fork example).

If you're ok with just a fire and forget thing, look at the 'use_system_1.pl' example. It uses a trick I saw about a million years ago: by passing '1' as the first param, it just spawns a process and then returns the pid (rather than an exit code). If I run that on my machine I get it's printout and then it starts the detached and then immediately exits. After a second, the detached process starts printing to the console. So, this means little to no control at all and especially, can't catch the exitcode of course, but is dead simple. But, since you do get the detached pid, it's likely you can play with the waitpid stuff similar to below if you're so inclined (I'm guessing that it internally does something very similar to the next example).

The other is 'use_fork.pl', which as it name implies, explicitly uses fork to kick off a separate process(*) in which to do a normal system call, so it can catch the exit code. The parent part of the fork uses waitpid with WNOHANG to illustrate that it can do stuff while the kid process hangs waiting for the detached process. In my case, it looks exactly as intended - it immediately forks, and on the console I get interweaved output from both the parent fork and from the detached kid, until the detached exits, the kid exits, and the fork is complete so it all ends. This means a bit more control and something nice can be done if the exitcode indicates a serious problem or whatever.

* a forked kid 'process' is on Win32 not quite a real fork, since there is no such thing in Win32. It's a pseudo-process (I'm assuming implemented by a thread...?), so in the kid you don't want to do real cute stuff to the interpreter since it might upset it. It's clearly visible as the pid for the kid is negative which isn't otherwise normal. But for this type of stuff I've never had problems...

Another possibly nice part of these code examples is that they will work equally on Win32/Unix. You probably want to look into how waitpid is used in more detail also, I have had multiple children going and been using '-1' in the waitpid call to pick them off and perhaps maintain a specific number of executing processes. Or whatever :-)

Hope this helps,

ken1


On 2016-08-02 20:02, John DePasquale wrote:

Thanks howard. I did try that option, as below:

Win32::Process::Create( $Win32processObj,

'e:\\programs\\dev\\batfile.bat',

'batfile.bat',

0,

DETACHED_PROCESS,

'.' ) ||  die "Failed to create process.\n";

Interestingly, this did not run the bat file at all ( though it did not produce the “Failed . . . “ error ). This same statement runs fine when I use NORMAL_PRIORITY_CLASS in place of DETACHED_PROCESS, meaning that it runs the bat file successfully. However, the parent process waits for the win32::process to complete before control is returned to the parent. Using DETACHED_PROCESS not only does not achieve the objective, it causes the child process to not run at all, for some reason.

John DePasquale

Chief Executive Officer

Paradigm Consulting

/“Proudly presenting the Vinopedia System”/

www.vinopedia.us <http://www.vinopedia.us/>

49 Dalby Street

Newton, MA 02458

Mobile: 617-610-2424

Fax: 617-600-7326

------------------------------------------------------------------------

*From:*Howard Tanner [mailto:tan...@optonline.net]
*Sent:* Tuesday, August 02, 2016 1:51 PM
*To:* 'John DePasquale'
*Subject:* RE: untethered child process

Did you use the DETACHED_PROCESS option on the Win32::Process->Create? This should in theory do what you want.

*From:* activeperl-boun...@listserv.activestate.com <mailto:activeperl-boun...@listserv.activestate.com> [mailto:activeperl-boun...@listserv.activestate.com] *On Behalf Of *John DePasquale
*Sent:* Tuesday, August 2, 2016 12:52 PM
*To:* activeperl@listserv.ActiveState.com <mailto:activeperl@listserv.ActiveState.com>
*Subject:* untethered child process

Hi all,

Is it truly possible to spawn a child process in perl on windows so that the parent process does NOT wait for the child process to finish before the parent continues its own processing? I’ve tried to accomplish this over the last couple of days using exec, system, wind32::process, proc::background, fork, and more, on windows server 2008 using perl 5.22.1. For each of these statements I’m able to spawn a child process that runs a .bat file successfully, but in each case the parent waits for the .bat file to finish processing ( it takes about 40 seconds ) before the parent proceeds. I’m beginning to think that this is not really possible on windows. I have found dozens of sites that detail usage of each of these statements and I’ve tried them all. I can get all of them to launch and complete a child process but I can’t get the parent to NOT wait for completion.

Any guidance is very gratefully appreciated. Thank you.

-john

John DePasquale

Chief Executive Officer

Paradigm Consulting

/“Proudly presenting the Vinopedia System”/

www.vinopedia.us <http://www.vinopedia.us/>

49 Dalby Street

Newton, MA 02458

Mobile: 617-610-2424

Fax: 617-600-7326

------------------------------------------------------------------------



_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

use strict;
use warnings;

$|=1;
my $wait = $ARGV[0] || 10;
print "Hello, I'm $0 as $$!\n";
for ( 1 .. $wait )
{
        sleep(1);
        print "$_/$wait\n";
};

exit(42);
use strict;
use warnings;

$|=1;
print "I'm $0 as $pid, about to start detached process...";
my $pid = system(1, qw(perl detached.pl));
print "$pid is now executing\n";
use strict;
use warnings;

use POSIX ":sys_wait_h";
    
$|=1;
print "Forking from $$!\n";
my $pid = fork();
die("Oops, fork failed...?") unless defined($pid);
if ($pid)
{
        print "I'm the parent $$, waiting for $pid and doing something while I 
wait\n";
        my $cntr = 1;
        while (!waitpid($pid, WNOHANG))
        {
                print "Loop $cntr...\n";
                sleep(1);
                $cntr++;
        }
        print "The forked $pid seems to be finished\n";
}
else
{
        sleep(1);
        print "I'm the forked $$, running detached...\n";
        my $xit = system(qw(perl detached.pl)) >> 8;
        print "The detached ended with exitcode $xit\n";
}
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to