本文整理汇总了PHP中pcntl_get_last_error函数的典型用法代码示例。如果您正苦于以下问题:PHP pcntl_get_last_error函数的具体用法?PHP pcntl_get_last_error怎么用?PHP pcntl_get_last_error使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了pcntl_get_last_error函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: signal_handler_sigchild
/**
* Handle parent registered sigchild callbacks.
*
* @param int $signal_number is the signal that called this function.
* @access public
*/
public function signal_handler_sigchild($signal_number)
{
// do not allow signals to interrupt this
declare (ticks=0) {
// reap all child zombie processes
if (self::$parent_pid == getmypid()) {
$status = '';
do {
// get child pid that exited
$child_pid = pcntl_waitpid(0, $status, WNOHANG);
if ($child_pid > 0) {
// child exited
$identifier = false;
if (!isset($this->forked_children[$child_pid])) {
$this->log("Cannot find {$child_pid} in array! (This may be a subprocess not in our fork)", self::LOG_LEVEL_INFO);
continue;
}
$child = $this->forked_children[$child_pid];
$identifier = $child['identifier'];
// call exit function if and only if its declared */
if ($child['status'] == self::WORKER) {
$this->invoke_callback($this->parent_function_child_exited[$this->forked_children[$child_pid]['bucket']], array($child_pid, $this->forked_children[$child_pid]['identifier']), true);
}
// stop the child pid
$this->forked_children[$child_pid]['status'] = self::STOPPED;
$this->forked_children_count--;
// respawn helper processes
if ($child['status'] == self::HELPER && $child['respawn'] === true) {
$this->log('Helper process ' . $child_pid . ' died, respawning', self::LOG_LEVEL_INFO);
$this->helper_process_spawn($child['function'], $child['arguments'], $child['identifier'], true);
}
// Poll for results from any children
$this->post_results($child['bucket']);
} elseif ($child_pid < 0) {
// ignore acceptable error 'No child processes' given we force this signal to run potentially when no children exist
if (pcntl_get_last_error() == 10) {
continue;
}
// pcntl_wait got an error
$this->log('pcntl_waitpid failed with error ' . pcntl_get_last_error() . ':' . pcntl_strerror(pcntl_get_last_error()), self::LOG_LEVEL_DEBUG);
}
} while ($child_pid > 0);
}
}
}
示例2: daemonize
/**
* Daemonize the current process so it can run in the background.
*
* If $pidfile is supplied, the process ID is written there.
* Provide absolute path names for the parameters to avoid file not found errors or logs inside the source code folder.
*
* If an error occurred, a RuntimeException is thrown.
*
* @param string $pidfile File to write the process ID of the daemon to
* @param string $stderr File to redirect STDERR to
* @param string $stdout File to redirect STDOUT to
* @param string $stdin File to read STDIN from
* @throws \RuntimeException
* @return true
*/
public static function daemonize($pidfile = null, $stderr = '/dev/null', $stdout = '/dev/null', $stdin = '/dev/null')
{
// Allow only cli scripts to daemonize, otherwise you may confuse your webserver
if (\php_sapi_name() !== 'cli') {
throw new \RuntimeException('Can only daemonize a CLI process!');
}
self::checkPID($pidfile);
self::reopenFDs($stdin, $stdout, $stderr);
if (($pid1 = @\pcntl_fork()) < 0) {
throw new \RuntimeException('Failed to fork, reason: "' . \pcntl_strerror(\pcntl_get_last_error()) . '"');
} elseif ($pid1 > 0) {
exit;
}
if (@posix_setsid() === -1) {
throw new \RuntimeException('Failed to become session leader, reason: "' . \posix_strerror(\posix_get_last_error()) . '"');
}
if (($pid2 = @\pcntl_fork()) < 0) {
throw new \RuntimeException('Failed to fork, reason: "' . \pcntl_strerror(\pcntl_get_last_error()) . '"');
} elseif ($pid2 > 0) {
exit;
}
chdir('/');
umask(022);
self::writePID($pidfile);
return true;
}
示例3: fork
/**
* @param \Extended\Process\Runnable $child
* A runnable process to fork
*/
public function fork(Runnable $child)
{
$this->pid = pcntl_fork();
if ($this->pid == -1) {
$error = pcntl_strerror(pcntl_get_last_error());
throw new ProcessException('Unable to fork the process: ' . $error);
} elseif ($this->pid) {
return pcntl_wait($this->pid);
}
self::$buffer->append($child->run());
}
示例4: fork
/**
* Fork.
*
* fork() helper method for php-resque
*
* @see pcntl_fork()
*
* @return Process|null An instance of Process representing the child in the parent, or null in the child.
* @throws \Resque\Component\Core\Exception\ResqueRuntimeException when cannot fork, or fork failed.
*/
public function fork()
{
if (!function_exists('pcntl_fork')) {
throw new ResqueRuntimeException('pcntl_fork is not available');
}
$this->setPidFromCurrentProcess();
$pid = pcntl_fork();
if ($pid === -1) {
throw new ResqueRuntimeException(sprintf('Unable to fork child. %s', pcntl_strerror(pcntl_get_last_error())));
}
if (0 === $pid) {
// Forked and we're the child, so return nothing.
return null;
}
$child = new self($pid);
return $child;
}
示例5: testWrite
public function testWrite()
{
$path = '/tmp/tmp.log';
$count = 100;
$workers = 10;
if (is_file($path)) {
unlink($path);
}
$message = '';
for ($i = 0; $i < 1000; ++$i) {
$message .= uniqid();
}
$message .= PHP_EOL;
$pids = [];
for ($w = 0; $w < $workers; ++$w) {
$pid = pcntl_fork();
if (function_exists('pcntl_get_last_error')) {
$error_number = pcntl_get_last_error();
$error = "[{$error_number}] " . pcntl_strerror($error_number);
} else {
$error = var_export(error_get_last(), true);
}
$this->assertNotSame(-1, $pid, "Can't fork: " . $error);
if ($pid) {
$pids[] = $pid;
} else {
$writer = new AppenderStream($path);
$writer->setUseLock(true);
$writer->setUseLockShortMessage(true);
for ($i = 0; $i < $count; ++$i) {
$writer->write(1, $message);
}
die;
}
}
foreach ($pids as $p) {
pcntl_waitpid($p, $status);
}
$this->assertSame(13001, strlen($message));
$c = str_pad('', $count * $workers * strlen($message), $message);
$this->assertSame($c, file_get_contents($path));
if (is_file($path)) {
unlink($path);
}
}
示例6: __construct
/**
* @param callable $callable
* @param array $arguments
*
* @throws \Brick\Process\ProcessException
*/
public function __construct(callable $callable, array $arguments = [])
{
self::checkExtensions();
$pid = @pcntl_fork();
if ($pid < 0) {
$errorCode = pcntl_get_last_error();
$errorMessage = pcntl_strerror($errorCode);
throw ProcessException::forkingError($errorCode, $errorMessage);
}
if ($pid) {
// Parent
$this->pid = $pid;
} else {
// Child
call_user_func_array($callable, $arguments);
exit(0);
}
}
示例7: run
public function run()
{
if ($this->stopped) {
return 0;
}
$pid = pcntl_fork();
if ($pid < 0) {
$errno = pcntl_get_last_error();
throw new \RuntimeException("Cannot fork process, error = " . pcntl_strerror($errno));
} elseif ($pid == 0) {
// in child process
$now = time();
if ($now < $this->nextRun) {
if ($this->traceEnabled) {
mdebug("Will wait %d seconds for next run of %s", $this->nextRun - $now, $this->name);
}
sleep($this->nextRun - $now);
}
// run using application
$this->application->setAutoExit(false);
// we will handle exit on our own
$this->application->setCatchExceptions(false);
// we will catch on our own
try {
$ret = $this->application->run($this->input, $this->output);
} catch (\Exception $e) {
mtrace($e, "Exception while running command {$this->name}", "error");
$ret = AbstractDaemonSentinelCommand::EXIT_CODE_COMMON_ERROR;
}
// Check if we should alert
if ($ret != AbstractDaemonSentinelCommand::EXIT_CODE_OK && $this->alert) {
// alert in child process is better, because we can get more trace here
malert("Daemon command %s failed with exit code = %d", $this->name, $ret);
exit(AbstractDaemonSentinelCommand::EXIT_CODE_OK);
// exit OK because alert is already sent
} else {
exit($ret);
}
} else {
$this->lastRun = $this->nextRun;
return $pid;
}
}
示例8: runCallable
/**
* @param callable $callable
* @param PromiseInterface $promise
* @return mixed The return value of the thread
*
* Method where all the implementation logic is to run the callable asynchronously.
*
* It must call $promise's setPromisedData when finished.
*/
protected function runCallable(callable $callable, PromiseInterface $promise)
{
$this->callableToRun = $callable;
fprintf(STDOUT, "Starting runCallable\n");
if (null !== $this->currentChildPid) {
// The deamon is already started, change the callable to execute
$this->setTerminated(false);
$this->hasToBeRun = true;
return;
}
// Start the deamon.
$this->currentChildPid = pcntl_fork();
if (-1 === $this->currentChildPid) {
throw new PcntlForkException(sprintf("The process could not be forked. Error message: %s", pcntl_get_last_error()));
} elseif (0 === $this->currentChildPid) {
fprintf(STDOUT, "Starting deamon\n");
fprintf(STDOUT, "Has to be run: %b\n", $this->hasToBeRun);
while (true) {
if ($this->hasToBeRun) {
$this->currentChildPid = posix_getpid();
// Here is the child space
try {
$childValue = call_user_func($this->callableToRun);
$succeed = true;
} catch (\Throwable $e) {
$childValue = $e;
$succeed = false;
}
fprintf(STDOUT, "Got output: %s\n", $childValue);
$promise->setPromisedData($childValue, $succeed);
$this->setTerminated();
fprintf(STDOUT, "Terminated: %b\n", $this->isTerminated());
$this->hasToBeRun = false;
}
}
}
}
示例9: run
/**
* @param callable $callback
* @param array $args
* @throws Exception
* @return int Child process PID
*/
public static function run(callable $callback, $args = [])
{
if (!function_exists('pcntl_fork')) {
throw new Exception('No pcntl is installed');
}
$pid = pcntl_fork();
if (-1 == $pid) {
throw new Exception('pcntl_fork() error: ' . pcntl_strerror(pcntl_get_last_error()));
}
if (0 != $pid) {
return $pid;
} else {
register_shutdown_function(function () {
ob_end_clean();
posix_kill(getmypid(), SIGKILL);
});
if (empty($args)) {
call_user_func($callback);
} else {
call_user_func_array($callback, $args);
}
exit(0);
}
}
示例10: waitForBackgroundProcesses
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));
}
}
}
}
}
示例11: doFork
protected function doFork(InputInterface $input, OutputInterface $output)
{
$pid = pcntl_fork();
if ($pid < 0) {
$errno = pcntl_get_last_error();
throw new \RuntimeException("Cannot fork process, error = " . pcntl_strerror($errno));
} elseif ($pid == 0) {
// in child process
$ret = $this->doExecute($input, $output);
exit(is_numeric($ret) ? $ret : 0);
} else {
return $pid;
}
}
示例12: fork
private function fork()
{
for ($i = 0; $i < 3; ++$i) {
if (isset($pid)) {
usleep(1000000);
}
$pid = pcntl_fork();
if ($pid >= 0) {
return $pid;
}
$error_number = pcntl_get_last_error();
$error = "[{$error_number}] " . pcntl_strerror($error_number);
Logger::getLogger('queue')->warn("Can`t fork, retryNumber={$i}, pid: '" . var_export($pid, true) . "', error: '{$error}'", new Exception());
}
throw new RuntimeException('Can`t fork');
}
示例13: checkWorkerExit
/**
* 监控worker进程状态,退出重启
* @param resource $channel
* @param int $flag
* @param int $pid 退出的进程id
* @return mixed
*/
public static function checkWorkerExit()
{
// 由于SIGCHLD信号可能重叠导致信号丢失,所以这里要循环获取所有退出的进程id
while (($pid = pcntl_waitpid(-1, $status, WUNTRACED | WNOHANG)) != 0) {
// 如果是重启的进程,则继续重启进程
if (isset(self::$workerToRestart[$pid]) && self::$serverStatus != self::STATUS_SHUTDOWN) {
unset(self::$workerToRestart[$pid]);
self::restartWorkers();
}
// 出错
if ($pid == -1) {
// 没有子进程了,可能是出现Fatal Err 了
if (pcntl_get_last_error() == 10) {
self::notice('Server has no workers now');
}
return -1;
}
// 查找子进程对应的woker_name
$pid_workname_map = self::getPidWorkerNameMap();
$worker_name = isset($pid_workname_map[$pid]) ? $pid_workname_map[$pid] : '';
// 没找到worker_name说明出错了 哪里来的野孩子?
if (empty($worker_name)) {
self::notice("child exist but not found worker_name pid:{$pid}");
break;
}
// 进程退出状态不是0,说明有问题了
if ($status !== 0) {
self::notice("worker exit status {$status} pid:{$pid} worker:{$worker_name}");
}
// 记录进程退出状态
self::$serverStatusInfo['worker_exit_code'][$worker_name][$status] = isset(self::$serverStatusInfo['worker_exit_code'][$worker_name][$status]) ? self::$serverStatusInfo['worker_exit_code'][$worker_name][$status] + 1 : 1;
// 更新状态到共享内存
self::updateStatusToShm();
// 清理这个进程的数据
self::clearWorker($worker_name, $pid);
// 如果服务是不是关闭中
if (self::$serverStatus != self::STATUS_SHUTDOWN) {
// 重新创建worker
self::createWorkers();
} else {
$all_worker_pid = self::getPidWorkerNameMap();
if (empty($all_worker_pid)) {
// 删除共享内存
self::removeShmAndQueue();
// 发送提示
self::notice("Server stoped");
// 删除pid文件
@unlink(WORKERMAN_PID_FILE);
exit(0);
}
}
//end if
}
//end while
}
示例14: checkWorkerExit
/**
* 监控worker进程状态,退出重启
* @param resource $channel
* @param int $flag
* @param int $pid 退出的进程id
* @return mixed
*/
public static function checkWorkerExit()
{
// 由于SIGCHLD信号可能重叠导致信号丢失,所以这里要循环获取所有退出的进程id
while (($pid = pcntl_waitpid(-1, $status, WUNTRACED | WNOHANG)) != 0) {
// 如果是重启的进程,则继续重启进程
if (isset(self::$pidsToRestart[$pid]) && self::$serviceStatus != self::STATUS_SHUTDOWN) {
unset(self::$pidsToRestart[$pid]);
self::restartPids();
}
// 出错
if ($pid < 0) {
self::notice('pcntl_waitpid return ' . $pid . ' and pcntl_get_last_error = ' . pcntl_get_last_error());
return $pid;
}
// 查找子进程对应的woker_name
$pid_workname_map = self::getPidWorkerNameMap();
$worker_name = isset($pid_workname_map[$pid]) ? $pid_workname_map[$pid] : '';
// 没找到worker_name说明出错了
if (empty($worker_name)) {
self::notice("child exist but not found worker_name pid:{$pid}");
break;
}
// 进程退出状态不是0,说明有问题了
if ($status !== 0) {
self::notice("worker[{$pid}:{$worker_name}] exit with status {$status}");
}
// 记录进程退出状态
self::$serviceStatusInfo['worker_exit_code'][$worker_name][$status] = isset(self::$serviceStatusInfo['worker_exit_code'][$worker_name][$status]) ? self::$serviceStatusInfo['worker_exit_code'][$worker_name][$status] + 1 : 1;
// 更新状态到共享内存
self::updateStatusToShm();
// 清理这个进程的数据
self::clearWorker($worker_name, $pid);
// 如果服务是不是关闭中
if (self::$serviceStatus != self::STATUS_SHUTDOWN) {
// 重新创建worker
self::spawnWorkers();
} else {
$all_worker_pid = self::getPidWorkerNameMap();
if (empty($all_worker_pid)) {
// 删除共享内存
self::removeShmAndQueue();
// 发送提示
self::notice("Workerman stoped");
// 删除pid文件
@unlink(WORKERMAN_PID_FILE);
exit(0);
}
}
//end if
}
//end while
}
示例15: getLastError
/**
* Get Last Error
*
* @return int Returns error code.
*/
public function getLastError()
{
return pcntl_get_last_error();
}