| 
<?php/**
 * PHP_Fork class usage examples
 * ==================================================================================
 * NOTE: In real world you surely want to keep each class into
 * a separate file, then include() it into your application.
 * For this examples is more useful to keep all_code_into_one_file,
 * so that each example shows a unique feature of the PHP_Fork framework.
 * ==================================================================================
 * action_dispatcher.php
 *
 * This example shows a multi-process application model built using PHP_Fork.
 * Execute-threads makes the work, but they don't use the infinite cycle run();
 * work are passed from the parent (console) to pseudo-thread using a remote
 * method call (PHP_FORK_VOID_METHOD), simulating the behaviour of a centralized
 * calls dispatcher.
 *
 *
 * ATTENTION: this feature of PHP_Fork is highly experimental;
 * all things are OK until we run such an example, that does nothing and simply
 * sleep() all time waiting for a call. Some experiement with real applications
 * seems to show that firing the child process with a signal (that is part of the
 * workaround...) causes the process to stop execution, and then to repeat ALL the
 * run() method after signal caught... This is not an acceptable behaviour and
 * should be tested better.
 *
 * ==================================================================================
 *
 * Copyright (c) 2003-2002 by Luca Mariano ([email protected])
 * http://www.lucamariano.it
 *
 * This program is free software. You can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License.
 */
 // Import of base class
 require_once ("../Fork.php");
 // Import of PEAR Mail class
 require_once ("Mail.php");
 // number of executeThreads we want
 define ("NUM_THREAD", 10);
 // SMTP host to use for mailing
 define ("SMTP_TEST_HOST", "smtp.consulenti.csi.it");
 // The example will send a lot of mails to this address, so keep sure it's one of yours...
 define ("MAIL_RECIPIENT", "[email protected]");
 // this is needed as PHP 4.3 in order to use pcntl_signal()
 declare (ticks = 1);
 
 /**
 *
 * executeThread class inherit from PHP_Fork and must redefine the run() method
 * all the code contained into the run() method will be executed only by the child
 * process; all other methods that you define will be accessible both to the parent
 * and to the child (and will be executed into the relative process)
 */
 class executeThread extends PHP_Fork {
 function executeThread($name)
 {
 $this->PHP_Fork($name);
 }
 
 function run()
 {
 // this thread sits sleeping until the dispatcher pass some work to it...
 while (true) {
 sleep(60);
 }
 }
 
 function sendMail($msgObj)
 {
 if ($this->_isChild) {
 $msgObj = &$msgObj[0];
 // to have a feedback of pseudo-thread cuncurrency level
 $msgObj['subject'] .= " posted at " . getmicrotime() . " from " . $this->getName();
 
 srand((double)microtime() * 1000000);
 
 $params["host"] = "smtp.consulenti.csi.it";
 
 $mail = &Mail::factory ("smtp", $params);
 
 $headers['From'] = $msgObj['from'];
 $headers['To'] = $msgObj['to'];
 $headers['Subject'] = $msgObj['subject'] . "(" . rand(0, 100000) . ")" ;
 
 $mail->send($msgObj['to'], $headers, $msgObj['body'] . "\n" . rand(0, 100000));
 }
 /**
 * Never change this line, it requires no adjustments...
 */
 else return $this->register_callback_func(func_get_args(), __FUNCTION__);
 }
 }
 
 /**
 * Functions used by the console
 */
 function _getInputCLI()
 {
 $opt = _read();
 $opt = strtoupper (trim($opt));
 return $opt;
 }
 
 function _read()
 {
 $fp = fopen("php://stdin", "r");
 $input = fgets($fp, 255);
 fclose($fp);
 
 return $input;
 }
 
 function getmicrotime()
 {
 list($usec, $sec) = explode(" ", microtime());
 return ((float)$usec + (float)$sec);
 }
 /**
 * Main program. Bring up n instances of the executeThread class that
 * runs concurrently. It's a multi-thread app with a few lines of code!!!
 */
 for ($i = 0;$i < NUM_THREAD;$i++) {
 $executeThread[$i] = &new executeThread ("executeThread-" . $i);
 $executeThread[$i]->start();
 echo "Started " . $executeThread[$i]->getName() . " with PID " . $executeThread[$i]->getPid() . "...\n";
 }
 
 print "This is the main process.\nPress [X] to terminate, [S] tells executeThreads to send " . NUM_THREAD . " mail msgs\n";
 
 /**
 * Console simple listener
 */
 while (true) {
 echo ">";
 
 $opt = _getInputCLI();
 echo "\n";
 switch ($opt) {
 case "X":
 // stops all threads
 for ($i = 0;$i < NUM_THREAD;$i++) {
 $executeThread[$i]->stop();
 echo "Stopped " . $executeThread[$i]->getName() . "\n";
 }
 exit;
 break;
 
 case "S":
 
 // compose the mail; here data are fixed, in a real application
 // data are read from a DB table (or a socket, a named pipe, etc)
 $msgObj = array();
 $msgObj['to'] = MAIL_RECIPIENT;
 $msgObj['from'] = "[email protected]";
 $msgObj['subject'] = "PHP_Fork test ";
 $msgObj['body'] = "Main program created this message at " . getmicrotime();
 
 echo "Sending mail to " . NUM_THREAD . " addresses...\n";
 $time_start = getmicrotime();
 
 // tells all running processes to send the same mail
 // in real word we should test if the the process is busy;
 // if not, we'll pass to it a $msgObj to process, then we'll remove
 // the $msgObj from message queue.
 for ($i = 0;$i < NUM_THREAD;$i++) {
 $executeThread[$i]->sendMail($msgObj);
 }
 $time_end = getmicrotime();
 $time = $time_end - $time_start;
 echo "Done! Elapsed " . $time . ", avg " . (($time / NUM_THREAD) * 1000) . " msecs/msg \n";
 break;
 }
 }
 
 ?>
 
 |