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

I need to have a perl script create a new process, and exit while it's child process continues running. I first tried with fork() which doesn't work because perlfork only creates a new psuedo-process (i.e., only creates a new thread), and the parent can't exit until the child returns.
if (my $ChildPid = fork) { # Parent - create lock and exit my $Lock = Childlck->new($ResName); $Lock->lock_mk($ChildPid); exit 0; } else { # Child - continue as G daemon exec $CMD, $CMDLineArgs, @ARGV; }
Next I tried with Win32::Process::Create, and it also exhibits the same problem...the parent doesn't "exit 0", until the child dies.
Win32::Process::Create($ChildProc, $CMD, $CMDLine, 0, 0, $CWD) || +LOG_MSG("E", "Could not spawn child: $!", 52099); $ChildPID = $ChildProc->GetProcessID(); LOG_MSG("I", "ChildPID = $ChildPID", 52099, $ChildPID); my $Lock = Glck->new($ResName); $Lock->lock_mk($ChildPID); LOG_MSG("I", "Online.pl is about to exit with 0.", 52099); exit (0);
Then I tried using system() to create a new perl process, but it also doesn't return from the parent script until the child dies.
system($CMDLine); my $Lock = Glck->new($ResName); LOG_MSG("I", "Online.pl is about to exit with 0.", 52099); exit (0);
How can I create a process and have the parent process return while the child process continues running?

Replies are listed 'Best First'.
Re: Can't get Win32::Create::Process() parent to exit before it's children
by BrowserUk (Patriarch) on Jan 20, 2010 at 01:39 UTC

    Use

    system( 1, $CMDLine);

    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.
      Thanks for responding. Late last night I solved the problem. Just for everyone's information and possible future use I will describe the solution. First off I tried calling system with the first parameter of '1', which was supposed to work, by asynchronously creating the new process and returning...but it didn't work either. Also system() is supposed to return the child PID, but it doesn't with the version of PERL that my system is running...it returns a process handle ID. Here is my PERL version.
      This is perl, v5.8.7 built for MSWin32-x86-multi-thread Copyright 1987-2005, Larry Wall
      Here is what I tried, and it didn't work. The parent process didn't return 0, until the child process exited.
      $ChildPID = system 1, $CMDLine; my $Lock = Glck->new($ResName); LOG_MSG("I", "Online.pl is about to exit with 0.", 52099); exit (0);
      The solution that worked is this. I went back to using Win32::Process::Create( ) but called it with the DETACHED_PROCESS creation flag set. And this worked as I wanted it to. Online.pl called Create() and then returned '0' back to my server.
      require Win32::Process; my $ParentPID; $ParentPID = $$; LOG_MSG("I", "ParentPID = $ParentPID before creating child.", 5209 +9, $ParentPID); Win32::Process::Create($ChildProc, $CMD, $CMDLine, 0, DETACHED_PRO +CESS, $CWD) || LOG_MSG("E", "Could not spawn child: $!", 52099); $ChildPID = $ChildProc->GetProcessID(); LOG_MSG("I", "ChildPID = $ChildPID", 52099, $ChildPID); my $Lock = Glck->new($ResName); $Lock->lock_mk($ChildPID); LOG_MSG("I", "Online.pl is about to exit with 0.", 52099); exit (0);
      Thanks for looking into this problem for me, I hope this solution helps some of you. I am sure that I will require all of your assistance in the future ;-)

        Thanks very much for posting this solution - you solved my problem as well!!!

        I had tried Win32::Process::Create(), and saw mention of the DETACHED_PROCESS flag, but had not yet tried it and wasn't sure how to specify it (as which parameter).

        I had spent a day or so trying different combinations of things trying to get this to work. If my child process was a Windows-type application, the parent exited. But if the child was a console-type application, the parent would wait for it. Upon specifying the DETACHED_PROCESS flag as in your example, the console-type application is now spawned and the parent exits.

        Eric S.
Re: Can't get Win32::Create::Process() parent to exit before it's children
by ikegami (Patriarch) on Jan 20, 2010 at 05:00 UTC
    You are mistaken. Win32::Process does not wait for the process it creates to finish (unless you call ->Wait).

      I never said Win32::Process::Create() waits for the newly created process to finish. I said the process which called Win32::Process::Create() didn't return it's own exit code until the newly created process exited.

      BTW,I solved my problem and posted the sol'n in this thread if you are interested.

Re: Can't get Win32::Create::Process() parent to exit before it's children
by cdarke (Prior) on Jan 20, 2010 at 06:42 UTC
    Is it maybe something to do with the locking you are doing?
    my $Lock = Glck->new($ResName); $Lock->lock_mk($ChildPID);
    Why are you doing that?