Re: untethered child process
Kenneth Ölwing <[email protected]> Tue, 2 Aug 2016 21:15:01 +0200
| Newsgroups | gmane.comp.lang.perl.active-perl |
|---|---|
| Message-ID | <[email protected]> |
This is a multi-part message in MIME format. --------------58F86DF44E9D9E398BCD6A4A Content-Type: multipart/alternative; boundary="------------19E670A07B0CA08490F65445" --------------19E670A07B0CA08490F65445 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 8bit 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:[email protected]] > *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:* [email protected] > <mailto:[email protected]> > [mailto:[email protected]] *On Behalf Of > *John DePasquale > *Sent:* Tuesday, August 2, 2016 12:52 PM > *To:* [email protected] > <mailto:[email protected]> > *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? Ive 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 Im 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. Im 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 Ive tried > them all. I can get all of them to launch and complete a child process > but I cant 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 > [email protected] > To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs --------------19E670A07B0CA08490F65445 Content-Type: text/html; charset=windows-1252 Content-Transfer-Encoding: 8bit <html> <head> <meta content="text/html; charset=windows-1252" http-equiv="Content-Type"> </head> <body bgcolor="#FFFFFF" text="#000000"> <p>Hi John,</p> <p>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...</p> <p>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...</p> <p>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).</p> <p>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).<br> </p> <p>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.</p> <p>* 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...<br> </p> <p>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 :-)</p> <p>Hope this helps,</p> <p>ken1<br> </p> <p><br> </p> <div class="moz-cite-prefix">On 2016-08-02 20:02, John DePasquale wrote:<br> </div> <blockquote cite="mid:[email protected]" type="cite"> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <meta name="Generator" content="Microsoft Word 14 (filtered medium)"> <!--[if !mso]><style>v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style><![endif]--> <style><!-- /* Font Definitions */ @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4;} @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4;} @font-face {font-family:Tahoma; panose-1:2 11 6 4 3 5 4 4 2 4;} @font-face {font-family:Verdana; panose-1:2 11 6 4 3 5 4 4 2 4;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {margin:0in; margin-bottom:.0001pt; font-size:11.0pt; font-family:"Calibri","sans-serif";} a:link, span.MsoHyperlink {mso-style-priority:99; color:blue; text-decoration:underline;} a:visited, span.MsoHyperlinkFollowed {mso-style-priority:99; color:purple; text-decoration:underline;} p.MsoAcetate, li.MsoAcetate, div.MsoAcetate {mso-style-priority:99; mso-style-link:"Balloon Text Char"; margin:0in; margin-bottom:.0001pt; font-size:8.0pt; font-family:"Tahoma","sans-serif";} p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph {mso-style-priority:34; margin-top:0in; margin-right:0in; margin-bottom:0in; margin-left:.5in; margin-bottom:.0001pt; font-size:11.0pt; font-family:"Calibri","sans-serif";} p.msonormal0, li.msonormal0, div.msonormal0 {mso-style-name:msonormal; mso-margin-top-alt:auto; margin-right:0in; mso-margin-bottom-alt:auto; margin-left:0in; font-size:12.0pt; font-family:"Times New Roman","serif";} span.EmailStyle19 {mso-style-type:personal; font-family:"Calibri","sans-serif"; color:windowtext;} span.EmailStyle20 {mso-style-type:personal; font-family:"Calibri","sans-serif"; color:#1F497D;} span.EmailStyle21 {mso-style-type:personal; font-family:"Calibri","sans-serif"; color:windowtext;} span.EmailStyle22 {mso-style-type:personal-reply; font-family:"Calibri","sans-serif"; color:#1F497D;} span.BalloonTextChar {mso-style-name:"Balloon Text Char"; mso-style-priority:99; mso-style-link:"Balloon Text"; font-family:"Tahoma","sans-serif";} .MsoChpDefault {mso-style-type:export-only; font-size:10.0pt;} @page WordSection1 {size:8.5in 11.0in; margin:1.0in 1.0in 1.0in 1.0in;} div.WordSection1 {page:WordSection1;} --></style><!--[if gte mso 9]><xml> <o:shapedefaults v:ext="edit" spidmax="1026" /> </xml><![endif]--><!--[if gte mso 9]><xml> <o:shapelayout v:ext="edit"> <o:idmap v:ext="edit" data="1" /> </o:shapelayout></xml><![endif]--> <div class="WordSection1"> <p class="MsoNormal"><span style="color:#1F497D">Thanks howard. I did try that option, as below:<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D">Win32::Process::Create( $Win32processObj,<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D"> 'e:\\programs\\dev\\batfile.bat',<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D"> 'batfile.bat',<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D"> 0,<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D"> DETACHED_PROCESS,<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D"> '.' ) || die "Failed to create process.\n";<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D">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.<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p> <div> <p class="MsoNormal"><span style="color:#1F497D">John DePasquale<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D">Chief Executive Officer<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D">Paradigm Consulting<o:p></o:p></span></p> <p class="MsoNormal"><i><span style="color:#1F497D">Proudly presenting the Vinopedia System<o:p></o:p></span></i></p> <p class="MsoNormal"><span style="color:#1F497D"><a moz-do-not-send="true" href="http://www.vinopedia.us/">www.vinopedia.us</a><o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D">49 Dalby Street<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D">Newton, MA 02458<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D">Mobile: 617-610-2424<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D">Fax: 617-600-7326</span><span style="font-family:"Verdana","sans-serif";color:#1F497D"><o:p></o:p></span></p> <div class="MsoNormal" style="text-align:center" align="center"><span style="font-family:"Verdana","sans-serif";color:#1F497D"> <hr align="center" size="2" width="100%"></span></div> </div> <p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p> <div> <div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in"> <p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> Howard Tanner [<a class="moz-txt-link-freetext" href="mailto:[email protected]">mailto:[email protected]</a>] <br> <b>Sent:</b> Tuesday, August 02, 2016 1:51 PM<br> <b>To:</b> 'John DePasquale'<br> <b>Subject:</b> RE: untethered child process<o:p></o:p></span></p> </div> </div> <p class="MsoNormal"><o:p> </o:p></p> <p class="MsoNormal"><span style="color:#1F497D">Did you use the DETACHED_PROCESS option on the Win32::Process->Create? This should in theory do what you want.<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p> <div> <div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in"> <p class="MsoNormal"><b>From:</b> <a moz-do-not-send="true" href="mailto:[email protected]">[email protected]</a> [<a moz-do-not-send="true" href="mailto:[email protected]">mailto:[email protected]</a>] <b>On Behalf Of </b>John DePasquale<br> <b>Sent:</b> Tuesday, August 2, 2016 12:52 PM<br> <b>To:</b> <a moz-do-not-send="true" href="mailto:[email protected]">[email protected]</a><br> <b>Subject:</b> untethered child process<o:p></o:p></p> </div> </div> <p class="MsoNormal"><o:p> </o:p></p> <p class="MsoNormal">Hi all,<o:p></o:p></p> <p class="MsoNormal">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? Ive 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 Im 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. Im 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 Ive tried them all. I can get all of them to launch and complete a child process but I cant get the parent to NOT wait for completion.<o:p></o:p></p> <p class="MsoNormal">Any guidance is very gratefully appreciated. Thank you.<o:p></o:p></p> <p class="MsoListParagraph" style="text-indent:-.25in">-<span style="font-size:7.0pt;font-family:"Times New Roman","serif""> </span>john<o:p></o:p></p> <p class="MsoNormal"><o:p> </o:p></p> <p class="MsoNormal"><span style="color:#1F497D">John DePasquale<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D">Chief Executive Officer<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D">Paradigm Consulting<o:p></o:p></span></p> <p class="MsoNormal"><i><span style="color:#1F497D">Proudly presenting the Vinopedia System<o:p></o:p></span></i></p> <p class="MsoNormal"><a moz-do-not-send="true" href="http://www.vinopedia.us/">www.vinopedia.us</a><o:p></o:p></p> <p class="MsoNormal"><span style="color:#1F497D">49 Dalby Street<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D">Newton, MA 02458<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D">Mobile: 617-610-2424<o:p></o:p></span></p> <p class="MsoNormal"><span style="color:#1F497D">Fax: 617-600-7326</span><span style="font-family:"Verdana","sans-serif";color:#1F497D"><o:p></o:p></span></p> <div class="MsoNormal" style="text-align:center" align="center"><span style="font-family:"Verdana","sans-serif";color:#1F497D"> <hr align="center" size="2" width="100%"></span></div> <p class="MsoNormal"><o:p> </o:p></p> </div> <br> <fieldset class="mimeAttachmentHeader"></fieldset> <br> <pre wrap="">_______________________________________________ ActivePerl mailing list <a class="moz-txt-link-abbreviated" href="mailto:[email protected]">[email protected]</a> To unsubscribe: <a class="moz-txt-link-freetext" href="http://listserv.ActiveState.com/mailman/mysubs">http://listserv.ActiveState.com/mailman/mysubs</a></pre> </blockquote> <br> </body> </html> --------------19E670A07B0CA08490F65445-- --------------58F86DF44E9D9E398BCD6A4A Content-Type: text/plain; charset=UTF-8; name="detached.pl" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="detached.pl" 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); --------------58F86DF44E9D9E398BCD6A4A Content-Type: text/plain; charset=UTF-8; name="use_system_1.pl" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="use_system_1.pl" 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"; --------------58F86DF44E9D9E398BCD6A4A Content-Type: text/plain; charset=UTF-8; name="use_fork.pl" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="use_fork.pl" 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"; } --------------58F86DF44E9D9E398BCD6A4A Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ ActivePerl mailing list [email protected] To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs --------------58F86DF44E9D9E398BCD6A4A--