Ejemplo n.º 1
0
 /**
  * Start the child processes. 
  *
  * This should only be called from the command line. It should be called 
  * as early as possible during execution.
  *
  * This will return 'child' in the child processes. In the parent process, 
  * it will run until all the child processes exit or a TERM signal is 
  * received. It will then return 'done'.
  */
 public function start()
 {
     // Trap SIGTERM
     pcntl_signal(SIGTERM, array($this, 'handleTermSignal'), false);
     do {
         // Start child processes
         if ($this->procsToStart) {
             if ($this->forkWorkers($this->procsToStart) == 'child') {
                 return 'child';
             }
             $this->procsToStart = 0;
         }
         // Check child status
         $status = false;
         $deadPid = pcntl_wait($status);
         if ($deadPid > 0) {
             // Respond to child process termination
             unset($this->children[$deadPid]);
             if ($this->flags & self::RESTART_ON_ERROR) {
                 if (pcntl_wifsignaled($status)) {
                     // Restart if the signal was abnormal termination
                     // Don't restart if it was deliberately killed
                     $signal = pcntl_wtermsig($status);
                     if (in_array($signal, self::$restartableSignals)) {
                         echo "Worker exited with signal {$signal}, restarting\n";
                         $this->procsToStart++;
                     }
                 } elseif (pcntl_wifexited($status)) {
                     // Restart on non-zero exit status
                     $exitStatus = pcntl_wexitstatus($status);
                     if ($exitStatus > 0) {
                         echo "Worker exited with status {$exitStatus}, restarting\n";
                         $this->procsToStart++;
                     }
                 }
             }
             // Throttle restarts
             if ($this->procsToStart) {
                 usleep(500000);
             }
         }
         // Run signal handlers
         if (function_exists('pcntl_signal_dispatch')) {
             pcntl_signal_dispatch();
         } else {
             declare (ticks=1) {
                 $status = $status;
             }
         }
         // Respond to TERM signal
         if ($this->termReceived) {
             foreach ($this->children as $childPid => $unused) {
                 posix_kill($childPid, SIGTERM);
             }
             $this->termReceived = false;
         }
     } while (count($this->children));
     pcntl_signal(SIGTERM, SIG_DFL);
     return 'done';
 }
Ejemplo n.º 2
0
 public function __construct(callable $callBack = null)
 {
     $plug = \PMVC\plug(PLUGIN);
     $plug->log("Monitor starting.");
     while (empty($plug[IS_STOP_ALL]) || count($plug[CHILDREN])) {
         if (!empty($plug[MY_PARENT])) {
             break;
         }
         // Check for exited children
         $pid = pcntl_wait($status, WNOHANG);
         if (isset($plug[CHILDREN][$pid])) {
             $exitCode = pcntl_wexitstatus($status);
             $plug->log("Child {$pid} was stopped with exit code of {$exitCode}");
             if (!$plug[IS_STOP_ALL] && 1 !== $exitCode) {
                 $callbackId = $plug[CHILDREN][$pid];
                 $plug['start']->restore($callbackId);
             }
             $plug->cleanPid($pid);
         }
         pcntl_signal_dispatch();
         if (empty($plug[CHILDREN])) {
             $plug[IS_STOP_ALL] = true;
             break;
         }
         if ($callBack && empty($plug[IS_STOP_ALL])) {
             call_user_func($callBack);
         }
         // php will eat up your cpu if you don't have this
         usleep(50000);
         pcntl_signal_dispatch();
     }
     $plug->log("Monitor was exited.");
 }
Ejemplo n.º 3
0
 /**
  * Handler for process signals.
  *
  * @param int $signo
  * @param int $pid
  * @param int $status
  */
 public function childSignalHandler($signo = null, $pid = null, $status = null)
 {
     //If no pid is provided, that means we're getting the signal from the system.  Let's figure out
     //which child process ended
     if (!$pid) {
         $pid = pcntl_waitpid(-1, $status, WNOHANG);
     }
     //Make sure we get all of the exited children
     while ($pid > 0) {
         if ($pid && isset($this->currentJobs[$pid])) {
             $exitCode = pcntl_wexitstatus($status);
             if ($exitCode == 0) {
                 $this->logger->debug('TestCase was successful finished.', ['pid' => $pid]);
             } else {
                 $this->logger->info('Process exited with status != 0.', ['pid' => $pid, 'exitCode' => $exitCode]);
                 $this->exitCode = $exitCode;
             }
             unset($this->currentJobs[$pid]);
         } else {
             if ($pid) {
                 //Oh no, our job has finished before this parent process could even note that it had been launched!
                 //Let's make note of it and handle it when the parent process is ready for it
                 $this->logger->debug('Adding process to signal queue.', ['pid' => $pid]);
                 $this->signalQueue[$pid] = $status;
             }
         }
         $pid = pcntl_waitpid(-1, $status, WNOHANG);
     }
 }
Ejemplo n.º 4
0
 public function child_signal_handler($signo, $pid = null, $status = null)
 {
     //If no pid is provided, that means we're getting the signal from the system.  Let's figure out
     //which child process ended
     if (!$pid) {
         $pid = pcntl_waitpid(-1, $status, WNOHANG);
     }
     //Make sure we get all of the exited children
     while ($pid > 0) {
         if ($pid && isset($this->current_jobs[$pid])) {
             $exit_code = pcntl_wexitstatus($status);
             if ($exit_code != 0) {
                 echo "{$pid} exited with status " . $exit_code . "\n";
             }
             unset($this->current_jobs[$pid]);
         } else {
             if ($pid) {
                 //Oh no, our job has finished before this parent process could even note that it had been launched!
                 echo "..... Adding {$pid} to the signal queue ..... \n";
                 $this->signal_queue[$pid] = $status;
             }
         }
         $pid = pcntl_waitpid(-1, $status, WNOHANG);
     }
     return true;
 }
Ejemplo n.º 5
0
 public function getStatus($status)
 {
     if (pcntl_wifexited($status)) {
         return pcntl_wexitstatus($status);
     }
     return 1;
 }
Ejemplo n.º 6
0
 /**
  * run a callback in parrallel thread
  *
  * @param callable $callback
  * @return void
  */
 public function run(\Closure $callback = null)
 {
     $callback = $callback ?: function () {
     };
     $children = array();
     while (!empty($this->works)) {
         $items = array_pop($this->works);
         $pid = pcntl_fork();
         if (-1 == $pid) {
             throw new \RuntimeException('無法使用子程序!');
         } elseif ($pid) {
             //子程序start
             $children[] = $pid;
             $this->onStart($pid);
         } else {
             try {
                 //子程序處理 callback
                 $callback($items);
                 exit(0);
             } catch (\Exception $e) {
                 exit($e->getCode());
             }
         }
     }
     if ($children) {
         foreach ($children as $child) {
             $res = pcntl_waitpid($child, $status);
             if ($res == -1 || $res > 0) {
                 //子程序end
                 $status = pcntl_wexitstatus($status);
                 $this->onExit($child, $status);
             }
         }
     }
 }
 protected function waitForBackground(InputInterface $input, OutputInterface $output)
 {
     $lastMemory = memory_get_usage(true);
     while (true) {
         $memory = memory_get_usage(true);
         if ($memory != $lastMemory) {
             $output->writeln(sprintf("memory change: %d, from %d to %d", $memory - $lastMemory, $lastMemory, $memory));
         }
         $lastMemory = $memory;
         $status = 0;
         $pid = pcntl_waitpid(-1, $status, WNOHANG);
         if ($pid == 0) {
             // no child process has quit
             //usleep(200 * 1000);
         } else {
             if ($pid > 0) {
                 // child process with pid = $pid exits
                 $exitStatus = pcntl_wexitstatus($status);
                 $this->onChildProcessExit($pid, $exitStatus, $input, $output);
             } else {
                 // error
                 $errno = pcntl_get_last_error();
                 if ($errno == PCNTL_ECHILD) {
                     // all children finished
                     mdebug("No more BackgroundProcessRunner children, continue ...");
                     break;
                 } else {
                     // some other error
                     throw new \RuntimeException("Error waiting for process, error = " . pcntl_strerror($errno));
                 }
             }
         }
     }
     return $this->isFailed ? self::EXIT_CODE_COMMON_ERROR : self::EXIT_CODE_OK;
 }
function excute($url = '', $data)
{
    connectRedis();
    $response = array();
    $loop = count($data);
    for ($i = 0; $i < $loop; $i++) {
        # code...
        $pid = pcntl_fork();
        if (!$pid) {
            // sleep(1);
            print "In child {$i}\n";
            if (array_key_exists($i, $data)) {
                $x = 7;
                $k = get_url($data[$i]);
                setRedis("data", $i);
            }
            exit($i);
        }
    }
    #process
    while (pcntl_waitpid(0, $status) != -1) {
        $status = pcntl_wexitstatus($status);
        echo "Child {$status} completed\n";
    }
    // dd($response);
    return $response;
}
Ejemplo n.º 9
0
 protected function onChildExit($pid, $status)
 {
     $workerId = -1;
     foreach ($this->workers as $k => $worker) {
         if ($pid == $worker->getPid()) {
             $workerId = $k;
             break;
         }
     }
     if ($workerId == -1) {
         throw new RuntimeException('unknown child pid');
     }
     if ($this->gotTerm) {
         $this->workers[$workerId]->callFromMasterOnTerm($status);
         unset($this->workers[$workerId]);
         return;
     }
     if (pcntl_wifexited($status) && 0 == pcntl_wexitstatus($status)) {
         $this->workers[$workerId]->callFromMasterOnSuccess($status);
         unset($this->workers[$workerId]);
         return;
     }
     $this->workers[$workerId]->callFromMasterOnError($status);
     $this->internalSpawnWorker($this->workers[$workerId]);
 }
Ejemplo n.º 10
0
 /**
  * 执行同步
  * @return bool
  */
 public function run()
 {
     while (1) {
         $online_user = $this->get_data('Online')->get_online_list();
         $user_num = count($online_user);
         if (empty($online_user)) {
             sleep($this->_set_interval_time);
             #等待一下
             break;
         }
         $threads = array();
         foreach ($this->_sync_tables as $table) {
             $pid = pcntl_fork();
             if ($pid == -1) {
                 echo "FORK ERROR \n";
                 return false;
             } else {
                 if ($pid) {
                     $threads[] = $pid;
                     echo "CREATE THREAD SUCESS CUR THREAD ID IS {$pid}\n";
                 } else {
                     $exec_starttime = microtime(true);
                     $this->sync($online_user, $table);
                     echo "syncdb {$user_num} execute {$table['table_name']} func run " . (microtime(true) - $exec_starttime) . "\n";
                     exit(1);
                 }
             }
         }
         /*
         			foreach($this->_sync_union as $union_table){
                         $pid = pcntl_fork();
                         if($pid == -1){
                             echo "FORK ERROR \n";
                             return false;
                         }else{
                             if($pid){
                                 $threads[] = $pid;
                                 echo "CREATE THREAD SUCESS CUR THREAD ID IS {$pid}\n";
                             }else{
                                 $exec_starttime = microtime(true);
                                 $this->sync_union($online_user,$union_table);
                                 echo "syncdb {$user_num} execute {$union_table['table_name']} func run ".(microtime(true)-$exec_starttime)."\n";
                                 exit(1);
                             }
                         }
                     }*/
         foreach ($threads as $thread_id) {
             pcntl_waitpid($thread_id, $status);
             echo "THREAD {$thread_id} NOW EXIT\n";
             if (pcntl_wifexited($status)) {
                 $c = pcntl_wexitstatus($status);
                 echo "CHILD EXIT PID {$thread_id} STATUS {$c}\n";
             }
         }
         echo "SyncDb SUCESS\n";
         sleep($this->_set_interval_time);
         #等待一下
     }
 }
Ejemplo n.º 11
0
 private function exitStatusOfLastChild($status)
 {
     $exitStatusOfLastChild = pcntl_wexitstatus($status);
     $lastChildExitedNormally = pcntl_wifexited($status);
     if ($exitStatusOfLastChild === 0 && !$lastChildExitedNormally) {
         $exitStatusOfLastChild = 1;
     }
     return $exitStatusOfLastChild;
 }
Ejemplo n.º 12
0
 /**
  * @return bool
  */
 public function isCompleted()
 {
     $pid = pcntl_waitpid($this->getPid(), $status, WNOHANG);
     if ($pid == -1 || $pid === $this->getPid()) {
         $this->status = pcntl_wexitstatus($status);
         return true;
     }
     return false;
 }
Ejemplo n.º 13
0
 /**
  * Wait for the background process to exit
  */
 public function join()
 {
     if ($this->_started) {
         $status = null;
         pcntl_waitpid($this->_childPid, $status);
         $this->_started = false;
         $this->_returnCode = pcntl_wexitstatus($status);
     }
     return $this->_returnCode;
 }
Ejemplo n.º 14
0
 /**
  * Start a thread
  */
 public function start()
 {
     $this->fork();
     if (!$this->pid) {
         $this->run();
         if (substr(PHP_SAPI, 0, 3) == 'cli') {
             exit;
         }
         pcntl_wexitstatus(null);
     }
 }
Ejemplo n.º 15
0
function pleac_Running_Another_Program()
{
    // Run a simple command and retrieve its result code.
    exec("vi {$myfile}", $output, $result_code);
    // -----------------------------
    // Use the shell to perform redirection.
    exec('cmd1 args | cmd2 | cmd3 >outfile');
    exec('cmd args <infile >outfile 2>errfile');
    // -----------------------------
    // Run a command, handling its result code or signal.
    $pid = pcntl_fork();
    if ($pid == -1) {
        die('cannot fork');
    } elseif ($pid) {
        pcntl_waitpid($pid, $status);
        if (pcntl_wifexited($status)) {
            $status = pcntl_wexitstatus($status);
            echo "program exited with status {$status}\n";
        } elseif (pcntl_wifsignaled($status)) {
            $signal = pcntl_wtermsig($status);
            echo "program killed by signal {$signal}\n";
        } elseif (pcntl_wifstopped($status)) {
            $signal = pcntl_wstopsig($status);
            echo "program stopped by signal {$signal}\n";
        }
    } else {
        pcntl_exec($program, $args);
    }
    // -----------------------------
    // Run a command while blocking interrupt signals.
    $pid = pcntl_fork();
    if ($pid == -1) {
        die('cannot fork');
    } elseif ($pid) {
        // parent catches INT and berates user
        declare (ticks=1);
        function handle_sigint($signal)
        {
            echo "Tsk tsk, no process interruptus\n";
        }
        pcntl_signal(SIGINT, 'handle_sigint');
        while (!pcntl_waitpid($pid, $status, WNOHANG)) {
        }
    } else {
        // child ignores INT and does its thing
        pcntl_signal(SIGINT, SIG_IGN);
        pcntl_exec('/bin/sleep', array('10'));
    }
    // -----------------------------
    // Since there is no direct access to execv() and friends, and
    // pcntl_exec() won't let us supply an alternate program name
    // in the argument list, there is no way to run a command with
    // a different name in the process table.
}
 /**
  * Analyzes the passed status code of a process and sets properties accordingly.
  * 
  * @param int $status
  * @author Dan Homorodean <*****@*****.**>
  */
 public function __construct($status)
 {
     if (pcntl_wifexited($status)) {
         $this->status = self::STATUS_EXITED;
         $this->exitCode = pcntl_wexitstatus($status);
     } elseif (pcntl_wifsignaled($status)) {
         $this->status = self::STATUS_SIGNALED;
         $this->reasonSignal = pcntl_wtermsig($status);
     } elseif (pcntl_wifstopped($status)) {
         $this->status = self::STATUS_STOPPED;
         $this->reasonSignal = pcntl_wstopsig($status);
     }
 }
Ejemplo n.º 17
0
function sig_handler($signo)
{
    switch ($signo) {
        case SIGCHLD:
            while (($x = pcntl_waitpid(0, $status, WNOHANG)) != -1) {
                if ($x == 0) {
                    break;
                }
                $status = pcntl_wexitstatus($status);
            }
            break;
    }
}
Ejemplo n.º 18
0
function test_exit_waits()
{
    print "\n\nTesting pcntl_wifexited and wexitstatus....";
    $pid = pcntl_fork();
    if ($pid == 0) {
        sleep(1);
        exit(-1);
    } else {
        $options = 0;
        pcntl_waitpid($pid, $status, $options);
        if (pcntl_wifexited($status)) {
            print "\nExited With: " . pcntl_wexitstatus($status);
        }
    }
}
 protected function waitForBackgroundProcesses()
 {
     //$lastMemory = memory_get_usage(true);
     while (true) {
         //$memory = memory_get_usage(true);
         //if ($memory != $lastMemory) {
         //    echo(
         //        sprintf("memory change: %d, from %d to %d", $memory - $lastMemory, $lastMemory, $memory)
         //        . PHP_EOL
         //    );
         //}
         //$lastMemory = $memory;
         pcntl_signal_dispatch();
         $status = 0;
         $pid = pcntl_waitpid(-1, $status, WNOHANG);
         if ($pid == 0) {
             // no child process has quit
             usleep(200 * 1000);
         } else {
             if ($pid > 0) {
                 // child process with pid = $pid exits
                 $exitStatus = pcntl_wexitstatus($status);
                 $runner = $this->runningProcesses[$pid];
                 if (!$runner instanceof CommandRunner) {
                     throw new \LogicException("Cannot find command runner for process pid = %d", $pid);
                 }
                 unset($this->runningProcesses[$pid]);
                 $runner->onProcessExit($exitStatus, $pid);
                 $newPid = $runner->run();
                 if ($newPid > 0) {
                     $this->runningProcesses[$newPid] = $runner;
                 }
             } else {
                 // error
                 $errno = pcntl_get_last_error();
                 if ($errno == PCNTL_ECHILD) {
                     // all children finished
                     mdebug("No more BackgroundProcessRunner children, continue ...");
                     break;
                 } else {
                     // some other error
                     throw new \RuntimeException("Error waiting for process, error = " . pcntl_strerror($errno));
                 }
             }
         }
     }
 }
Ejemplo n.º 20
0
 public function execute(CommittedJob $job, LogProvider $logProvider)
 {
     $traceStream = tmpfile();
     $child = pcntl_fork();
     if (!$child) {
         $this->executeInChild($job, $logProvider, $traceStream);
     }
     $childStatus = null;
     pcntl_wait($childStatus);
     $exitCode = pcntl_wexitstatus($childStatus);
     if ($exitCode !== 0) {
         rewind($traceStream);
         $e = new \RuntimeException(sprintf("Process for job %s exited non-zero: %d", $job->getId(), $exitCode));
         $e->traceString = stream_get_contents($traceStream);
         throw $e;
     }
 }
Ejemplo n.º 21
0
 public function childSignalHandler($signo, $pid = null, $status = null)
 {
     if (!$pid) {
         $pid = pcntl_waitpid(-1, $status, WNOHANG);
     }
     while ($pid > 0) {
         if ($pid && isset($this->currentJobs[$pid])) {
             $exitCode = pcntl_wexitstatus($status);
             if ($exitCode != 0) {
             }
             unset($this->currentJobs[$pid]);
         } else {
             if ($pid) {
                 $this->signalQueue[$pid] = $status;
             }
         }
         $pid = pcntl_waitpid(-1, $status, WNOHANG);
     }
     return true;
 }
 function executeAllChecks()
 {
     $fedsList = $this->getDataFromJson->obtainFederationsList();
     $this->storeResultsDb->storeFedsIntoDb($fedsList);
     $this->storeResultsDb->cleanOldEntityChecks();
     $idpList = $this->getDataFromJson->obtainIdPList();
     $this->storeResultsDb->updateIgnoredEntities();
     $count = 0;
     for ($i = 0; $i < $this->parallel; $i++) {
         $pid = pcntl_fork();
         if (!$pid) {
             sleep(1);
             //In child
             $this->storeResultsDb->resetDbConnection();
             print "Executing check for " . $idpList[$count]['entityID'] . "\n";
             $this->executeIdPchecks($idpList[$count], $this->fedsDisabled);
             return false;
         }
         $count++;
     }
     while (pcntl_waitpid(0, $status) != -1) {
         $status = pcntl_wexitstatus($status);
         if ($count < count($idpList)) {
             $pid = pcntl_fork();
             if (!$pid) {
                 sleep(1);
                 //In child
                 $this->storeResultsDb->resetDbConnection();
                 print "Executing check for " . $idpList[$count]['entityID'] . "\n";
                 $this->executeIdPchecks($idpList[$count], $this->fedsDisabled);
                 return false;
             }
             $count++;
         }
     }
     // End of all cycles
     $this->storeResultsDb->resetDbConnection();
     $this->storeResultsDb->deleteOldEntities();
     $this->storeResultsDb->storeFederationStats();
     return true;
 }
Ejemplo n.º 23
0
 /**
  * Seperate the job from the worker via pcntl_fork
  *
  * @param Job $job
  */
 public function perform(Job $job)
 {
     $this->child = Resque::fork();
     // Forked and we're the child. Run the job.
     if ($this->child === 0) {
         parent::perform($job);
         exit(0);
     }
     // Parent process, sit and wait
     if ($this->child > 0) {
         $status = 'Forked ' . $this->child . ' at ' . strftime('%F %T');
         $this->worker->updateProcLine($status);
         $this->worker->log($status);
         // Wait until the child process finishes before continuing
         pcntl_wait($status);
         $exitStatus = pcntl_wexitstatus($status);
         if ($exitStatus !== 0) {
             $job->fail(new Job\DirtyExitException('Job exited with exit code ' . $exitStatus));
         }
     }
     $this->child = null;
 }
Ejemplo n.º 24
0
 /**
  * Start serving requests to the application
  * @param Kelpie_Application
  */
 public function start($app)
 {
     if (!($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) {
         throw new Kelpie_Exception(socket_strerror(socket_last_error()));
     }
     if (!socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
         throw new Kelpie_Exception(socket_strerror(socket_last_error()));
     }
     if (!socket_bind($socket, $this->_host, $this->_port)) {
         throw new Kelpie_Exception(socket_strerror(socket_last_error()));
     }
     if (!socket_listen($socket)) {
         throw new Kelpie_Exception(socket_strerror(socket_last_error()));
     }
     // Prefork a number of child processes to handle incoming connections
     $maxConcurrency = 5;
     $procs = array();
     while (true) {
         if (-1 == ($pid = pcntl_fork())) {
             throw new Kelpie_Exception('Could not fork');
         } else {
             if ($pid == 0) {
                 $this->_child($socket, $app);
                 exit(0);
             } else {
                 $procs[$pid] = $pid;
             }
         }
         if (count($procs) >= $maxConcurrency) {
             if (-1 == ($pid = pcntl_wait($status))) {
                 throw new Kelpie_Exception('Something went wrong in pcntl_wait');
             }
             $exitStatus = pcntl_wexitstatus($status);
             unset($procs[$pid]);
         }
     }
 }
Ejemplo n.º 25
0
 public function actionIndex()
 {
     if ($rssSources = RssSources::findAll(["active" => "1"])) {
         foreach ($rssSources as $source) {
             Yii::$app->getDb()->close();
             $pid = pcntl_fork();
             Yii::$app->getDb()->open();
             if (!$pid) {
                 if ($source->is_full == 0) {
                     $detector = new RssNewsDetectorComponent($source);
                     $detector->run();
                 } else {
                     $parser = new RssNewsParserComponent($source);
                     $parser->run();
                 }
                 Yii::$app->end();
             }
         }
         while (pcntl_waitpid(0, $status) != -1) {
             $status = pcntl_wexitstatus($status);
             echo "Child {$status} completed\n";
         }
     }
 }
             if ($optGenerateContent === true) {
                 $object->body = file_get_contents('xmltextsource.txt');
             }
             $object->publish();
             eZExecution::cleanExit();
         }
     }
 }
 if ($script->verboseOutputLevel() > 0) {
     $cli->output("Main process: waiting for children...");
 }
 $errors = 0;
 while (!empty($currentJobs)) {
     foreach ($currentJobs as $index => $pid) {
         if (pcntl_waitpid($pid, $exitStatus, WNOHANG) > 0) {
             $exitCode = pcntl_wexitstatus($exitStatus);
             if ($exitCode != 0) {
                 $errors++;
                 if (!$optQuiet) {
                     if ($script->verboseOutputLevel() > 0) {
                         $cli->output("process #{$pid} exited with code {$exitCode}");
                     }
                 }
             } else {
                 if (!$optQuiet) {
                     if ($script->verboseOutputLevel() > 0) {
                         $cli->output("process #{$pid} exited successfully");
                     }
                 }
             }
             unset($currentJobs[$index]);
Ejemplo n.º 27
0
<?php

$pid = pcntl_fork();
if ($pid == 1) {
    die("failed");
} else {
    if ($pid) {
        $status = 0;
        pcntl_wait($status, WUNTRACED);
        var_dump(pcntl_wifexited($status));
        posix_kill($pid, SIGCONT);
        pcntl_wait($status);
        var_dump(pcntl_wifsignaled($status));
        var_dump(pcntl_wifstopped($status));
        var_dump(pcntl_wexitstatus($status));
        var_dump(pcntl_wait($status, WNOHANG | WUNTRACED));
        var_dump(pcntl_wait());
        var_dump(pcntl_waitpid());
        var_dump(pcntl_wifexited());
        var_dump(pcntl_wifstopped());
        var_dump(pcntl_wifsignaled());
        var_dump(pcntl_wexitstatus());
        var_dump(pcntl_wtermsig());
        var_dump(pcntl_wstopsig());
    } else {
        posix_kill(posix_getpid(), SIGSTOP);
        exit(42);
    }
}
Ejemplo n.º 28
0
 /**
  * Method to return the exit code of a terminated child process.
  *
  * @param   integer  $status  The status parameter is the status parameter supplied to a successful call to pcntl_waitpid().
  *
  * @return  integer  The child process exit code.
  *
  * @codeCoverageIgnore
  * @see     pcntl_wexitstatus()
  * @since   11.3
  */
 protected function pcntlChildExitStatus($status)
 {
     return pcntl_wexitstatus($status);
 }
Ejemplo n.º 29
0
 /**
  * Create a savegame fork.
  *
  * The savegame contains the current execution state, and can be resumed in
  * the event that the worker dies unexpectedly (for example, by encountering
  * a PHP fatal error).
  */
 private function createSavegame()
 {
     // the current process will become the savegame
     $this->savegame = posix_getpid();
     $pid = pcntl_fork();
     if ($pid < 0) {
         throw new \RuntimeException('Unable to create savegame fork.');
     } elseif ($pid > 0) {
         // we're the savegame now... let's wait and see what happens
         pcntl_waitpid($pid, $status);
         // worker exited cleanly, let's bail
         if (!pcntl_wexitstatus($status)) {
             posix_kill(posix_getpid(), SIGKILL);
         }
         // worker didn't exit cleanly, we'll need to have another go
         $this->createSavegame();
     }
 }
Ejemplo n.º 30
0
 /**
  * Spawns workers until one of them returns Sera_WorkerFarm::SPAWN_TERMINATE.
  * @return void
  */
 public function spawn()
 {
     // needed for PHP 5.2
     if (!function_exists('pcntl_signal_dispatch')) {
         declare (ticks=1);
     }
     $this->catchSignals();
     $this->_children = array();
     $parent = getmypid();
     $this->onStart();
     $this->_logger->info("spawning workers");
     // enter spawn loop
     while (!$this->_terminate || count($this->_children)) {
         // needed for PHP 5.3
         if (function_exists('pcntl_signal_dispatch')) {
             pcntl_signal_dispatch();
         }
         // if we haven't hit the process limit yet
         if (!$this->_terminate && count($this->_children) < $this->getProcessLimit()) {
             $this->_spawnWorker($this->_children);
         } else {
             // patiently wait for a child to die
             if (($pid = pcntl_wait($status, WUNTRACED)) > 0) {
                 unset($this->_children[$pid]);
                 // check the exit code
                 if (pcntl_wexitstatus($status) == self::SPAWN_TERMINATE && !$this->_terminate) {
                     foreach (array_keys($this->_children) as $pid) {
                         posix_kill($pid, SIGINT);
                     }
                     $this->_terminate = true;
                 }
             } else {
                 // if wait fails, check each child
                 $this->_reapWorkers($this->_children);
             }
         }
     }
     $this->_logger->debug("workers are finished, terminating");
     $this->onTerminate(0);
 }