Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Multi-OS Perl fork

by aplonis (Pilgrim)
on Sep 05, 2005 at 22:21 UTC ( #489301=snippet: print w/ replies, xml ) Need Help??

Description:

How to launch a wholly independent process on either Unix or Win32 all in same script.

This is part of an XML-RPC Client/Server pair available at the URL below:

XML-RPC Client/Server Pair

#!/usr/pkg/bin/perl 
# gus_xml-rpc_reboot.pl
# Copyright 2005-09-08 by Gan Uesli Starling
# XML-RPC server reboot script written in Perl.
# 42 liines of code & 30 comment lines.
# For use with this XML-RPC Client/Server pair:
# 1. gus_xml-rpc_server.pl
# 2. gus_xml-rpc_client_tk.pl

# HOW IT WORKS:
# On command, the running server reboots itsels as follows:
# 3. Launches this script in manner similar to below.
# 4. Dies when this script kills it.
# 5. Is reborn when new version launched by this script.

# Args sent by the to-be-restarted, still-running server.
my ( $script_path, $script_list, $local_port, 
     $prefork_pid, $plain_pw, $crypt_key ) = @ARGV;

# Lay running server to rest.
kill 15, $prefork_pid; sleep 5; # Gently persuade at first.
kill  2, $prefork_pid; sleep 5; # If ignored, insist harder.
kill  9, $prefork_pid; sleep 5; # If still ignored, use hammer.

# Prepare launch-string for use with 'Process::Create' on Win32.
# Note: Since this is a string, not a list, any scalars which
# are empty may cause problems. Make sure empty any empty 
# scalars are represented by empty double-quotes or else are
# left out entirely, as below.
my $win32_cmd = "wperl $script_path/gus_xml-rpc_server.pl "
    . "--script_list $script_list "
    . "--local_port $local_port "
    . "--password $plain_pw "
    . "--gui 0 ";

# On the off chance that key is empty.
$win32_cmd .= "--crypt_key $crypt_key " if $crypt_key;

# Prepare launch-array for use with 'fork' on Unix.
my @unix_cmd = (
    "perl", "$script_path/gus_xml-rpc_server.pl", 
    "--script_list", "$script_list",
    "--local_port", "$local_port",
    "--crypt_key", "$crypt_key",
    "--password", "$plain_pw",
    "--gui", "0"
);

# Launch new process the UNIX way.
sub unix_fork_process {
    if ( defined( my $kid = fork ) ) {
        unless ($kid) { 
            exec(@_) or die "Oops! Cannot exec.";
        }
    }
}

# Launch new process the Win32 way.
sub win32_create_process {
    my $win32_cmd = shift;
    require Win32::Process;
    require Win32;
    no strict;
    my $obj;

    sub ErrorReport{
        print Win32::FormatMessage( Win32::GetLastError() );
    }

    Win32::Process::Create(
        $obj, "C:\\Perl\\bin\\wperl.exe",
        "$win32_cmd", 0, NORMAL_PRIORITY_CLASS, "."
    ) || die ErrorReport();
}

# Launch new process any way whichever...
if ($^O =~ /Win32/i) { win32_create_process($win32_cmd) }
else { unix_fork_process(@unix_cmd) }
Comment on Multi-OS Perl fork
Download Code
Re: Multi-OS Perl fork
by jonadab (Parson) on Sep 06, 2005 at 13:39 UTC

    Are you saying that fork() doesn't work as advertised on Win32? That would be news to me. Or does your Win32 code do something additional that fork() does not do? What? I'm confused; perhaps you could explain?

      I haven't seen any "advertising" for fork() on Win32, but it doesn't work well enough. It seems to work for the people who implemented it, for their exact needs. It cannot work well with sockets and it has problems when running longer processes.

      I've never mustered the strength to track down these problems, but I'm quite sure that they stem from the fact that the fork() emulation is just that, an emulation, and that the parent and forked child are not separated completely. It was easy enough to circumvent this problem in my case, by writing Schedule::Cron::Nofork, but in many other cases, especially test programs, fork() Just Doesn't Work on Win32.

        I haven't seen any "advertising" for fork() on Win32

        By "as advertised", I didn't mean "as advertised specifically for Win32" but more like "as explained in standard documentation, such as the Camel book". I learned Perl from the 2nd ed. Camel while I was still using Windows 95 OSR2, with ActivePerl, and fork *seemed* to work for me, although I never used it extensively.

        It cannot work well with sockets and it has problems when running longer processes.

        Ah. I was not aware of these limitations. I knew that fork didn't work on DOS, but I was not aware that it had issues on Windows.

Back to Snippets Section

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://489301]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (2)
As of 2014-09-21 00:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (165 votes), past polls