Page 1 of 1

forking or process control in php

Posted: Mon Oct 25, 2004 7:34 am
by amolkad
I need help for process contrl .

Following is my code where in while loop i have switch case. In switch case for each value different files get included. Each this file has socket connection code and some database functionality.I need to apply process control functions here so that i can open different sockets at a time.
Please guide me for same.

Code: Select all

while($arr)
{
  switch ($case)
  {
    case 'one':
    include"one.php";
    break;
    case 'two':
    include"two.php";
    break;
    case 'three':
    include"three.php";
    break;
  }
}
Weirdan | Help us, help you. Please use

Code: Select all

and

Code: Select all

tags where approriate when posting code. Read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url][/color]

Posted: Mon Oct 25, 2004 8:00 am
by Weirdan
Let me check if I get you right: you want to start several processes at once and then control them?

Posted: Mon Oct 25, 2004 8:13 am
by amolkad
Thanks for reply,

Each included file has fsockopen code where the request get send and reply get parsed and get inserted in Db.
The switch case has currently 8 cases. Each case get executed one by one.Becos of socket code in each file process becomes slow.
So i need to executes the all files at a time.so that socket connections will be done as the same time.
is it possible?

Posted: Mon Oct 25, 2004 9:09 am
by Weirdan
are those includes self-contained? Do they need something from parent process, does parent process need something from them (exit codes, status updates, something else) ?

BTW, what's your host OS?

Posted: Mon Oct 25, 2004 12:53 pm
by kettle_drum
You cant strictly add threads within php but you could certainly call a bash script or something to run all the required php scripts at the same time. It might be faster to just run them one after another as then each script can have more system resources to complete its task.

Posted: Mon Oct 25, 2004 12:56 pm
by Weirdan
kettle_drum wrote:You cant strictly add threads within php
Take a look: [php_man]pcntl[/php_man]

Posted: Tue Oct 26, 2004 3:44 am
by amolkad
are those includes self-contained?>>>yes those files are self contained

Do they need something from parent process, does parent process need something from them (exit codes, status updates, something else) ? >>>no these are independent of each other. No relation in between them.

Posted: Tue Oct 26, 2004 5:43 am
by Weirdan
Then you can start them in background like this:

Code: Select all

$pids = array();
$pids[] = system("/path/to/script.php & echo $!");
$pids[] = system("/path/to/script2.php & echo $!");
$pids[] = system("/path/to/script2.php & echo $!");
var_dump("Started three scripts in background:");
var_dump($pids);
assuming that you use *nix as a host system and bash as a shell

Posted: Tue Oct 26, 2004 7:50 am
by amolkad
thanks for help
I will implement it if it reduces the execution time.

Posted: Tue Oct 26, 2004 8:33 am
by amolkad
sorry i forgot to mentioned that we have some session and global variable which we need to use in those included files.
so system command will not work.
is there any other option?

Posted: Tue Oct 26, 2004 11:45 am
by Weirdan
amolkad wrote:sorry i forgot to mentioned that we have some session and global variable which we need to use in those included files.
It's not a problem as you may store global variable to session and pass session id to child script. E.g.:

Code: Select all

<?php
 $a = 'blah-blah-blah';
 $b = 'something';
 session_start();
 
 function save_globals($which) {
     unset($_SESSIONї'GLOBALS']);
     foreach($GLOBALS as $key => $val)
        if( in_array($key, $which) )
            $_SESSIONї'GLOBALS']ї$key] = $val;
 }

 /* 
  * start multiple tasks in background                        
  *                                                           
  * each task will get sessionID as its last parameter        
  * to access session variables of the parent script you would use it like:
  *   //....
  *   if($argv) session_id( end($argv) );
  *   session_start();
  *   //....
  * 
  * selected variables from the global scope of the 
  * parent script will be available as 
  *     $_SESSIONї'GLOBALS']ї$variable_name]
  * e.g. $_SESSIONї'GLOBALS']ї'a'], $_SESSIONї'GLOBALS']ї'b'] 
  * 
  * you might want to extract($_SESSIONї'GLOBALS']) for your
  * convenience, e.g.:
  *   //.....
  *   extract($_SESSIONї'GLOBALS']);
  *   do_something_with($a); // '$a' is imported from the global scope of the
  *                          // parent script
  *   //.....                                            
  */
 function start_background_tasks($commands, $vars) {
     save_globals($vars);
     session_write_close();
     $pids = array();
     foreach($commands as $key => $command) {
         ob_start();
         $pidsї$key] = system($command . ' ' . session_id() . ' >/dev/null & echo $!');
         ob_end_clean();
     }
     return $pids;
 }

 $commands = array(
         'php script1.php',
         'php script2.php',
         //...and so forth
 );
 $pids = start_background_tasks($commands, array('a', 'b'));
 echo '<pre>Started tasks in background. Process IDs are:';
 print_r($pids);
 echo '</pre>';
 //.......
?>

Code: Select all

<?php
set_time_limit(0);
if( $argv ) session_id( end($argv) );
session_start();
extract($_SESSIONї'GLOBALS']);
session_write_close();
sleep(rand(30,60));
$fp = fopen('/tmp/1.log', 'a');
fputs($fp, $a);
fclose($fp);
?>

Code: Select all

<?php
set_time_limit(0);
if( $argv ) session_id( end($argv) );
session_start();
extract($_SESSIONї'GLOBALS']);
session_write_close();
sleep(rand(30,60));
$fp = fopen('/tmp/2.log', 'a');
fputs($fp, $b);
fclose($fp);
?>
as you can see, main.php starts two child processes and immidiately exits after then. Each child process then sleeps for a while, opens a file and writes the content of a variable imported from the global scope of main.php to its own file. Child processes in this example have full access to the session variables of the main script, as well as read-only access to the selected variables from the global context of their parent.

Posted: Tue Oct 26, 2004 11:57 am
by Weirdan
interesting enough, one can communicate with a background task via session as if it was shared memory segment... I never thought about that.... hmm...

[edit]
seems like default session handlers sometimes do not respect session_write_close. :evil:

am I talking to myself? :roll:
[/edit]