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