Search code examples
perlsocketssignals

How do I call a perl process that is already running from another script?


Problem: scriptA.cgi is sitting in an infinite loop and handling an open socket to a Flash client. scriptB.cgi is called from the web, does what it needs to do and then needs to inform scriptA to send a message to the client.

Is this possible? I'm stuck on how to have scriptB identify the instance of scriptA that is sitting there with the socket connection, rather than launching one of its own.

all thoughts appreciated.


Solution

  • If the communication needs are simple, this is a good application for signals.

    Edited to store process id from scriptA and read it in scriptB -- scripts A and B have to agree on a name.

     # script B
     do_scriptB_job();
     if (open(my $PID_FILE, "<", "scriptA.pid.file")) {
       $process_id_for_scriptA = <$PID_FILE>;
       close $PID_FILE;
       kill 'USR1', $process_id_for_scriptA;  # makes scriptA run the SIGUSR1 handler
     }
    
    
     # script A
     open(my $PID_FILE, ">", "scriptA.pid.file");
     print $PID_FILE $$;
     close $PID_FILE;
     my $signaled = 0;
     $SIG{"USR1"} = \sub { $signaled = 1 } # simple SIGUSR1 handler, set a variable
     while ( in_infinite_loop ) {
         if ($signaled) {
             # this block runs only if SIGUSR1 was received 
             # since last time this block was run
             send_a_message_to_the_client();
             $signaled = 0;
         } else {
             do_something_else();
         }
     }
     unlink "scriptA.pid.file";   # cleanup
    

    When script A receives a SIGUSR1 signal, the script will be interrupted to run the USR1 signal handler, setting $signaled. The thread of execution will then resume and the script can use the information.