Пример #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';
 }
Пример #2
0
 public final function execute()
 {
     $hasThreads = function_exists('pcntl_signal');
     if (!$hasThreads || Cli::getInstance()->isSimulation()) {
         flush();
         try {
             return $this->executeNoThread();
         } catch (Interrupt $e) {
             throw $e;
         } catch (Exception $e) {
             echo $e;
         }
         return;
     }
     pcntl_signal(SIGCHLD, SIG_IGN);
     $pid = pcntl_fork();
     if ($pid < 1) {
         $this->_run();
         posix_kill(posix_getpid(), 9);
         pcntl_waitpid(posix_getpid(), $temp = 0, WNOHANG);
         pcntl_wifexited($temp);
         exit;
         //Make sure we exit...
     } else {
         $this->pid = $pid;
     }
 }
Пример #3
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]);
 }
Пример #4
0
 public function getStatus($status)
 {
     if (pcntl_wifexited($status)) {
         return pcntl_wexitstatus($status);
     }
     return 1;
 }
Пример #5
0
 private function process()
 {
     $messageType = NULL;
     $messageMaxSize = 1024;
     while (TRUE) {
         if (count($this->childs) < $this->max) {
             echo count($this->childs) . " ";
             if (msg_receive($this->queue, QUEUE_TYPE_START, $messageType, $messageMaxSize, $this->message)) {
                 $pid = pcntl_fork();
                 if ($pid == -1) {
                     die('could not fork' . PHP_EOL);
                 } else {
                     if ($pid) {
                         $this->childs[$pid] = TRUE;
                         $messageType = NULL;
                         $this->message = NULL;
                     } else {
                         sleep(3);
                         $this->complete($messageType, $this->message);
                         exit;
                     }
                 }
                 foreach ($this->childs as $pid => $value) {
                     if (pcntl_waitpid($pid, $status, WNOHANG)) {
                         if (pcntl_wifexited($status)) {
                             unset($this->childs[$pid]);
                         }
                     }
                 }
             }
         }
         sleep(1);
     }
 }
Пример #6
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);
         #等待一下
     }
 }
Пример #7
0
 private function exitStatusOfLastChild($status)
 {
     $exitStatusOfLastChild = pcntl_wexitstatus($status);
     $lastChildExitedNormally = pcntl_wifexited($status);
     if ($exitStatusOfLastChild === 0 && !$lastChildExitedNormally) {
         $exitStatusOfLastChild = 1;
     }
     return $exitStatusOfLastChild;
 }
Пример #8
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);
     }
 }
Пример #10
0
 function reaper($signal)
 {
     $pid = pcntl_waitpid(-1, $status, WNOHANG);
     if ($pid == -1) {
         // No child waiting. Ignore it.
     } else {
         if (pcntl_wifexited($signal)) {
             echo "Process {$pid} exited.\n";
         } else {
             echo "False alarm on {$pid}\n";
         }
         reaper($signal);
     }
     pcntl_signal(SIGCHLD, 'reaper');
 }
Пример #11
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);
        }
    }
}
Пример #12
0
function process_execute($input)
{
    $pid = pcntl_fork();
    //创建子进程
    if ($pid == 0) {
        //子进程进入了这个岔路口,父进程直接执行if后面的代码
        $pid = posix_getpid();
        echo "* Process {$pid} was created, and Executed:\n\n";
        eval($input);
        //解析命令
        exit;
        //子进程必须退出,否则还会继续执行if后面的代码
    } else {
        //主进程
        $pid = pcntl_wait($status, WUNTRACED);
        //取得子进程结束状态
        if (pcntl_wifexited($status)) {
            echo "\n\n* Sub process: {$pid} exited with {$status}";
        }
    }
}
Пример #13
0
 function worker_onexit($pw, $revents)
 {
     cy_log(CYE_DEBUG, "in worker_onexit");
     if (!is_object($pw) && get_class($pw) !== 'EvChild') {
         cy_log(CYE_ERROR, 'error type param, in worker_onexit');
         return;
     }
     $pw->stop();
     $pid = $pw->rpid;
     pcntl_waitpid($pid, $status, WNOHANG);
     $wiexit = pcntl_wifexited($status);
     $status = $pw->rstatus;
     $worker = $this->workers[$pid];
     $key = $worker['key'];
     unset($this->workers[$pid]);
     if ($this->flag === WKST_RUNNING || $this->flag === WKST_SPAWN) {
         $this->worker_fork($key);
     } elseif ($this->flag === WKST_END) {
         $now_num = cy_i_get('bps_srv_' . $key . '_num', CY_TYPE_SYS);
         if ($now_num === 0) {
             $this->loop->stop();
         }
     }
     cy_i_dec("bps_srv_" . $key . "_num", CY_TYPE_SYS, 1);
     cy_i_del("bps_srv_lock_" . $pid, CY_TYPE_SYS);
     if ($wiexit) {
         return;
     }
     /* 子进程没有正常退出, 加保护性代码,防止进程因为被kill而死锁 */
     if ($flag === WKST_QUITING) {
         cy_log(CYE_TRACE, $pid . ' exit, receive master cmd.');
     } else {
         cy_log(CYE_ERROR, $pid . ' is not normal exited.');
     }
     // TCP Server Only
     $stat_lock = cy_i_get($stat_name, CY_TYPE_SYS);
     if ($stat_lock) {
         cy_unlock('bps_' . $key . '_lock');
     }
     usleep(100000);
 }
Пример #14
0
                    if (!empty($follower_users)) {
                        foreach ($follower_users as $user) {
                            $tmp_redis->lpush('request_queue', $user[1]);
                        }
                    }
                    Log::info('empty follower_users u_id' . $tmp_u_id);
                    echo "--------get " . count($follower_users) . " followers users done--------\n";
                }
                $tmp_redis->zadd('already_get_queue', 1, $tmp_u_id);
                $tmp_redis->close();
                $endTime = microtime();
                $startTime = explode(' ', $startTime);
                $endTime = explode(' ', $endTime);
                $total_time = $endTime[0] - $startTime[0] + $endTime[1] - $startTime[1];
                $timecost = sprintf("%.2f", $total_time);
                echo "--------const  " . $timecost . " second on {$tmp_u_id}--------\n";
            } else {
                echo "--------user {$tmp_u_id} info and followee and follower already get--------\n";
            }
            exit($i);
        }
        usleep(1);
    }
    while (pcntl_waitpid(0, $status) != -1) {
        $status = pcntl_wexitstatus($status);
        if (pcntl_wifexited($status)) {
            echo "yes";
        }
        echo "--------{$status} finished--------\n";
    }
}
Пример #15
0
 public function isExited()
 {
     return null !== $this->status && pcntl_wifexited($this->status);
 }
        if ($stream === $server && count($children) < 2) {
            $conn = @stream_socket_accept($server, -1, $peer);
            if (!is_resource($conn)) {
                continue;
            }
            echo "Starting a new child process for {$peer}\n";
            $pid = pcntl_fork();
            if ($pid > 0) {
                $children[] = $pid;
            } elseif ($pid === 0) {
                // Child process, implement our echo server
                $childPid = posix_getpid();
                fwrite($conn, "You are connected to process {$childPid}\n");
                while ($buf = fread($conn, 4096)) {
                    fwrite($conn, $buf);
                }
                fclose($conn);
                // We are done, quit.
                exit(0);
            }
        }
    }
    // Do housekeeping on exited childs
    foreach ($children as $i => $child) {
        $result = pcntl_waitpid($child, $status, WNOHANG);
        if ($result > 0 && pcntl_wifexited($status)) {
            unset($children[$i]);
        }
    }
    echo "\t" . count($children) . " connected\r";
}
Пример #17
0
 /**
  * Causes the current thread to die.
  *
  * The relative process is killed and disappears immediately from the
  * processes list.
  *
  * @return boolean
  */
 public function stop()
 {
     $success = false;
     if ($this->_pid > 0) {
         $status = 0;
         posix_kill($this->_pid, 9);
         pcntl_waitpid($this->_pid, $status, WNOHANG);
         $success = pcntl_wifexited($status);
         $this->_cleanProcessContext();
     }
     return $success;
 }
 protected function send_mail_sendmail($from, $to, $subject, $hdr, $body)
 {
     $cmd = escapeshellcmd(conf('mail.sendmail.path')) . ' -t -i -f ' . escapeshellarg($from);
     // $cmd = escapeshellcmd(conf('mail.sendmail.path')) . ' -t -i';
     $h = popen($cmd, 'w');
     if (!$h) {
         return "SENDMAIL: can't open pipe ({$cmd})";
     }
     fputs($h, $hdr);
     fputs($h, $body);
     $stat = pclose($h);
     if (function_exists('pcntl_wifexited')) {
         if (!pcntl_wifexited($stat)) {
             return 'SENDMAIL: abnormal sendmail process terminate';
         }
         $res = pcntl_wexitstatus($stat);
     } else {
         if (version_compare(phpversion(), '4.2.3') == -1) {
             $res = $stat >> 8 & 0xff;
         } else {
             $res = $stat;
         }
     }
     if ($res) {
         return "SENDMAIL: error occurred (cmd: {$cmd}) (code: {$res})";
     }
     return '';
 }
Пример #19
0
 /**
  * Check exit code and return TRUE if process was ended successfully.
  *
  * @return bool
  */
 public function isSuccessExit()
 {
     $this->exitCode = pcntl_wexitstatus($this->status);
     return pcntl_wifexited($this->status) && $this->exitCode === 0;
 }
Пример #20
0
 public function isNormalExit() : bool
 {
     return pcntl_wifexited($this->getStatus());
 }
Пример #21
0
 /**
  * update the process status
  *
  * @param bool $block
  */
 protected function updateStatus($block = false)
 {
     if ($this->running !== true) {
         return;
     }
     if ($block) {
         $res = pcntl_waitpid($this->pid, $status);
     } else {
         $res = pcntl_waitpid($this->pid, $status, WNOHANG | WUNTRACED);
     }
     if ($res === -1) {
         throw new \RuntimeException('pcntl_waitpid failed. the process maybe available');
     } elseif ($res === 0) {
         $this->running = true;
     } else {
         if (pcntl_wifsignaled($status)) {
             $this->term_signal = pcntl_wtermsig($status);
         }
         if (pcntl_wifstopped($status)) {
             $this->stop_signal = pcntl_wstopsig($status);
         }
         if (pcntl_wifexited($status)) {
             $this->errno = pcntl_wexitstatus($status);
             $this->errmsg = pcntl_strerror($this->errno);
         } else {
             $this->errno = pcntl_get_last_error();
             $this->errmsg = pcntl_strerror($this->errno);
         }
         if (pcntl_wifsignaled($status)) {
             $this->if_signal = true;
         } else {
             $this->if_signal = false;
         }
         $this->running = false;
     }
 }
Пример #22
0
 /**
  * Forks the process and runs the given method. The parent then waits
  * for the child process to signal back that it can continue
  *
  * @param   string  $method  Class method to run after forking
  *
  */
 protected function fork_me($method)
 {
     $this->wait_for_signal = true;
     $pid = pcntl_fork();
     switch ($pid) {
         case 0:
             $this->isparent = false;
             $this->parent_pid = $this->pid;
             $this->pid = getmypid();
             $this->{$method}();
             break;
         case -1:
             $this->log("Failed to fork");
             $this->stop_work = true;
             break;
         default:
             $this->log("Helper forked with pid {$pid}", GearmanManager::LOG_LEVEL_PROC_INFO);
             $this->helper_pid = $pid;
             while ($this->wait_for_signal && !$this->stop_work) {
                 usleep(5000);
                 pcntl_waitpid($pid, $status, WNOHANG);
                 if (pcntl_wifexited($status) && $status) {
                     $this->log("Helper child exited with non-zero exit code {$status}.");
                     exit(1);
                 }
             }
             break;
     }
 }
Пример #23
0
 /**
  * Execute a Closure as another process in the background while showing a
  * status update. The status update can be an indefinite spinner or a string
  * periodically sent from the background process, depending on whether the
  * provided Closure object has a $socket parameter or not. Messaging to the
  * main process is done by socket_* functions. The return value is either
  * the return value of the background process, or false if the process fork
  * failed.
  *
  * @param callable $callable Closure object
  * @return bool|int
  * @throws \Exception
  */
 public static function work(\Closure $callable)
 {
     if (!extension_loaded('pcntl')) {
         throw new \Exception('pcntl extension required');
     }
     if (!extension_loaded('sockets')) {
         throw new \Exception('sockets extension required');
     }
     $spinner = array('|', '/', '-', '\\');
     $i = 0;
     $l = count($spinner);
     $delay = 100000;
     $func = new \ReflectionFunction($callable);
     $socket = (bool) $func->getNumberOfParameters();
     if ($socket) {
         $sockets = array();
         if (socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $sockets) === false) {
             return false;
         }
     }
     $pid = pcntl_fork();
     if ($pid > 0) {
         $done = false;
         $retval = 0;
         pcntl_signal(SIGCHLD, function () use($pid, &$done, &$retval) {
             $child_pid = pcntl_waitpid($pid, $status);
             if (pcntl_wifexited($status)) {
                 $retval = pcntl_wexitstatus($status);
             }
             $done = true;
         });
         if ($socket) {
             $text = '';
             while (!$done) {
                 $r = array($sockets[1]);
                 $w = null;
                 $e = null;
                 if ($status = socket_select($r, $w, $e, 0)) {
                     $data = socket_read($sockets[1], 4096, PHP_NORMAL_READ);
                     if ($data === false) {
                         throw new \Exception(sprintf('socket write error %s', socket_strerror(socket_last_error($sockets[1]))));
                     }
                     echo str_repeat(chr(8), strlen($text));
                     $text = rtrim($data, "\n");
                     Console::stdout($text);
                 } else {
                     pcntl_signal_dispatch();
                 }
                 usleep($delay);
             }
             echo str_repeat(chr(8), strlen($text));
             socket_close($sockets[0]);
             socket_close($sockets[1]);
         } else {
             while (!$done) {
                 pcntl_signal_dispatch();
                 echo $spinner[$i];
                 usleep($delay);
                 echo chr(8);
                 $i = $i === $l - 1 ? 0 : $i + 1;
             }
         }
         return $retval;
     } elseif ($pid === 0) {
         if ($socket) {
             call_user_func($callable, $sockets[0]);
         } else {
             call_user_func($callable);
         }
         exit;
     } else {
         // Unable to fork process.
         return false;
     }
 }
 public function multi_test_stress_run_execute($tests_to_run_concurrently = 3, $total_loop_time = false)
 {
     $continue_test_flag = true;
     pts_client::$display->test_run_process_start($this);
     $this->disable_dynamic_run_count();
     $this->multi_test_stress_run = $tests_to_run_concurrently;
     $possible_tests_to_run = $this->get_tests_to_run();
     $tests_pids_active = array();
     $loop_until_time = is_numeric($total_loop_time) && $total_loop_time > 1 ? time() + $total_loop_time : false;
     while (!empty($possible_tests_to_run) || !empty($tests_pids_active)) {
         if ($continue_test_flag == false) {
             break;
         }
         $test_types_active = array();
         foreach ($tests_pids_active as $pid => &$test) {
             $ret = pcntl_waitpid($pid, $status, WNOHANG | WUNTRACED);
             if ($ret) {
                 if (pcntl_wifexited($status) || !posix_getsid($pid)) {
                     unset($tests_pids_active[$pid]);
                     continue;
                 }
             }
             if (!in_array($test->test_profile->get_test_hardware_type(), $test_types_active)) {
                 array_push($test_types_active, $test->test_profile->get_test_hardware_type());
             }
         }
         if (!empty($possible_tests_to_run) && count($tests_pids_active) < $tests_to_run_concurrently && (!$total_loop_time || $loop_until_time > time())) {
             shuffle($possible_tests_to_run);
             $test_to_run = false;
             $test_run_index = -1;
             foreach ($possible_tests_to_run as $i => $test) {
                 if (!in_array($test->test_profile->get_test_hardware_type(), $test_types_active)) {
                     $test_run_index = $i;
                     $test_to_run = $test;
                 }
             }
             if ($test_run_index == -1) {
                 $test_run_index = array_rand(array_keys($possible_tests_to_run));
                 $test_to_run = $possible_tests_to_run[$test_run_index];
             }
             $pid = pcntl_fork();
             if ($pid == -1) {
                 echo 'Forking failure.';
             } else {
                 if ($pid) {
                     $tests_pids_active[$pid] = $test_to_run;
                 } else {
                     $continue_test_flag = $this->process_test_run_request($test_to_run);
                     return false;
                 }
             }
             if ($total_loop_time == false) {
                 unset($possible_tests_to_run[$test_run_index]);
             } else {
                 if ($total_loop_time == 'infinite') {
                     echo 'Continuing to test indefinitely' . PHP_EOL;
                 } else {
                     if ($loop_until_time > time()) {
                         $time_left = ceil(($loop_until_time - time()) / 60);
                         echo 'Continuing to test for ' . $time_left . ' more minutes' . PHP_EOL;
                     } else {
                         echo 'TOTAL_LOOP_TIME elapsed; quitting....' . PHP_EOL;
                         break;
                     }
                 }
             }
         }
         sleep(1);
     }
     foreach ($this->get_tests_to_run() as $run_request) {
         // Remove cache shares
         foreach (pts_file_io::glob($run_request->test_profile->get_install_dir() . 'cache-share-*.pt2so') as $cache_share_file) {
             unlink($cache_share_file);
         }
     }
     return true;
 }
 /**
  * _mp_pollWorkers_forExit
  *
  * Polls children for exit statuses
  */
 private function _mp_pollWorkers_forExit()
 {
     $this->_debug("-----> " . __CLASS__ . '::' . __FUNCTION__ . '()', 9);
     $this->_debug("Polling workers for exit statuses", 9);
     foreach ($this->_workers as $workerId => $workerData) {
         $status = NULL;
         $r = pcntl_waitpid($workerData['pid'], $status, WNOHANG);
         if ($r == -1) {
             throw new A2o_AppSrv_Exception("PCNTL ERROR: {$r}");
         }
         if ($r == 0) {
             // worker is still alive
             $this->_debug("Worker {$workerId} is still alive", 9);
             continue;
         } else {
             if ($r != $workerData['pid']) {
                 throw new A2o_AppSrv_Exception("Invalid pid {$r}");
             }
             // what kind of exit
             if (pcntl_wifexited($status)) {
                 if ($status == 0) {
                     $this->_debug("Worker {$workerId} exited normally ({$status})");
                 } else {
                     $this->_warning("Worker {$workerId} died  with status {$status}");
                 }
             } else {
                 $this->_warning("Worker {$workerId} died with status {$status}");
             }
             $this->_mp_unregisterWorker($workerId);
         }
     }
 }
Пример #26
0
 /**
  * Checks if status code represents a normal exit.
  *
  * @return bool
  */
 public function isExited()
 {
     return pcntl_wifexited($this->status);
 }
Пример #27
0
 /**
  * W If Exited
  * @param $status The status parameter is the status parameter supplied to a successful call to pcntl_waitpid().
  *
  * @return bool Returns TRUE if the child status code represents a normal exit, FALSE otherwise.
  */
 public function wIfExited($status)
 {
     return pcntl_wifexited($status);
 }
Пример #28
0
 protected function onSIGCHLD($pid, $status)
 {
     if ($pid <= 0) {
         $this->logger->warn(sprintf('process PID is negative (pid: %s)', $pid));
         return;
     }
     $this->logger->info(sprintf("Childs: (%s)", join(", ", array_keys($this->childs))));
     if (key_exists($pid, $this->childs)) {
         unset($this->childs[$pid]);
         $this->logger->debug(sprintf("Child termination options. " . "wifexited: %d, wifsignaled: %d, wifstopped: %d, stopForking: %d", pcntl_wifexited($status), pcntl_wifsignaled($status), pcntl_wifstopped($status), $this->stopForking));
         // In case of unnormal exit fork new child process
         // 1. status=65280 when child process died with fatal error (set by PHP)
         // 2. exit=9 when child was terminated by parent or by unhandled exception (set by ProcessPool)
         // 3. stopeed by signal
         $crashed = pcntl_wifexited($status) && $status == 65280 || pcntl_wifexited($status) && pcntl_wexitstatus($status) == self::$termExitCode || pcntl_wifsignaled($status);
         if ($crashed) {
             $this->logger->info(sprintf("Child PID: %s crashed (status: %s, wifexited: %s, wifsignaled: %s)", $pid, $status, pcntl_wifexited($status), pcntl_wifsignaled($status)));
         } else {
             $this->logger->info(sprintf("Child PID: %s seems normally terminated (status: %s, wifexited: %s, wifsignaled: %s)", $pid, $status, pcntl_wifexited($status), pcntl_wifsignaled($status)));
         }
         $numTasks = $this->workQueue ? $this->workQueue->capacity() : 0;
         if ($numTasks) {
             $this->logger->info(sprintf("Work queue still has %d unhandled tasks", $numTasks));
         }
         if ($crashed || $numTasks) {
             try {
                 if (!$this->stopForking) {
                     $this->logger->info("Forking new worker process");
                     $this->forkChild(false);
                 } else {
                     $this->logger->info("Flag stopForking=1 prevents new process forking");
                 }
             } catch (Scalr_System_Ipc_Exception $e) {
                 $this->logger->error(sprintf("Cannot fork child. Caught: <%s> %s", get_class($e), $e->getMessage()));
             }
         }
     } else {
         $this->logger->info(sprintf("Child PID: %s is unknown. Known childs: (%s)", $pid, join(",", array_keys($this->childs))));
     }
 }
Пример #29
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);
    }
}
Пример #30
0
 public function testStart_Start2ProcessWithOnePidFile()
 {
     $pidfile = $this->_pidFile;
     $process = \Comos\Qpm\Process\Process::fork(function () use($pidfile) {
         $man = new Manager($pidfile);
         $man->start();
         usleep(200 * 1000);
     });
     usleep(100 * 1000);
     $man1 = new Manager($pidfile);
     $process1 = $man1->getProcess();
     $this->assertTrue($process1 instanceof \Comos\Qpm\Process\Process);
     try {
         $man2 = new Manager($this->_pidFile);
         $man2->start();
         $this->fail('expects Exception');
     } catch (\Exception $e) {
         $st = 0;
         $pidfile = pcntl_wait($st);
         $this->assertEquals($pidfile, $process->getPid());
         $this->assertEquals($pidfile, $process1->getPid());
         $this->assertTrue(\pcntl_wifexited($st));
         $this->assertTrue($e instanceof \Comos\Qpm\Pid\Exception);
         $this->assertEquals('process exists, no need to start a new one', $e->getMessage());
     }
 }