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? 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
> [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:&quot;Verdana&quot;,&quot;sans-serif&quot;;color:#1F497D"><o:p></o:p></span></p>
          <div class="MsoNormal" style="text-align:center"
            align="center"><span
style="font-family:&quot;Verdana&quot;,&quot;sans-serif&quot;;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:&quot;Tahoma&quot;,&quot;sans-serif&quot;">From:</span></b><span
style="font-size:10.0pt;font-family:&quot;Tahoma&quot;,&quot;sans-serif&quot;">
                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-&gt;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? 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.<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:&quot;Times New
            Roman&quot;,&quot;serif&quot;">          </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:&quot;Verdana&quot;,&quot;sans-serif&quot;;color:#1F497D"><o:p></o:p></span></p>
        <div class="MsoNormal" style="text-align:center" align="center"><span
style="font-family:&quot;Verdana&quot;,&quot;sans-serif&quot;;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--