/**
* 运行指令
* @param callable|null $callback
* @return self
* @throws \RuntimeException
* @throws ProcessFailedException
*/
public function mustRun($callback = null)
{// 运行指令
if ($this->isSigchildEnabled() && !$this->enhanceSigchildCompatibility) {
// 如果是个 单独进程 可以,但是 单独预习的环境不行
throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
}// 这里异常
if (0 !== $this->run($callback)) {// 如果 执行 回调 函数 结果 不是 0
throw new ProcessFailedException($this);// 抛出异常
}
return $this;// 返回对象本身
}// 两个特殊情况异常检测 外包执行,执行完成后,返回对象本身
/**
* 启动进程并写到 STDIN 输入后返回。
* @param callable|null $callback
* @throws \RuntimeException
* @throws \RuntimeException
* @throws \LogicException
*/
public function start($callback = null)
{// 启动进程 并写到 STDIN 输入后返回
if ($this->isRunning()) {// 如果当前的正在运行,抛出异常 进程执行中
throw new \RuntimeException('Process is already running');
}
if ($this->outputDisabled && null !== $callback) {// 如果禁止输出 并且 回调函数不为空
throw new \LogicException('Output has been disabled, enable it to allow the use of a callback.');
}// 必须允许 回调函数存在
$this->resetProcessData();//重置进程 数据
$this->starttime = $this->lastOutputTime = microtime(true);// 进程开始时间
$this->callback = $this->buildCallback($callback);// 创建回调函数
$descriptors = $this->getDescriptors();// 获取描述
$commandline = $this->commandline;// 命令行 命令 进行转移
if ('\\' === DS && $this->enhanceWindowsCompatibility) {// 如果 分隔符 为 \ 并且 允许执行窗口命令
$commandline = 'cmd /V:ON /E:ON /C "(' . $commandline . ')';// 通过 cmd 命令执行
foreach ($this->processPipes->getFiles() as $offset => $filename) {// 进程管道获取文件
$commandline .= ' ' . $offset . '>' . Utils::escapeArgument($filename);// 进行命令组合
}
$commandline .= '"';// 组合成为新命令
if (!isset($this->options['bypass_shell'])) {// 如果没有设置 bypass_shell 的方式
$this->options['bypass_shell'] = true;
}
}
// 通过进程 函数 进行 执行,可以通过php 来执行 命令行程序
$this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options);
if (!is_resource($this->process)) {// 如果进程执行完成 不是 资源句柄
throw new \RuntimeException('Unable to launch a new process.');// 进程有问题,哈哈
}
$this->status = self::STATUS_STARTED;// 状态 等于 当前程序执行状态
if ($this->tty) {// 如果是这个鬼东西
return;
}
$this->updateStatus(false);// 更新状态
$this->checkTimeout();// 更新 输出时间
}
/**
* 重启进程
* @param callable|null $callback
* @return Process
* @throws \RuntimeException
* @throws \RuntimeException
*/
public function restart($callback = null)
{// 重启进程
if ($this->isRunning()) {// 异常抛出
throw new \RuntimeException('Process is already running');
}
$process = clone $this;// 复制一份
// 在 类实例化 普通的 复制是不行的,必须是 clone 才是真正的复制,跟变量不一样
$process->start($callback);// 重启
return $process;// 返回 复制的进程
}
/**
* 等待要终止的进程
* @param callable|null $callback
* @return int
*/
public function wait($callback = null)
{// 等待要终止的进程
$this->requireProcessIsStarted(__FUNCTION__);// 当前函数进入到 请求进程 是否开始的判读
$this->updateStatus(false);//更新 状态
if (null !== $callback) {// 如果 为空
$this->callback = $this->buildCallback($callback);// 回调函数重见
}
do {// 执行
$this->checkTimeout();// 跳出
$running = '\\' === DS ? $this->isRunning() : $this->processPipes->areOpen();// 根据不同的情形 判断是否 running
$close = '\\' !== DS || !$running;
$this->readPipes(true, $close);
} while ($running);// 当循环
while ($this->isRunning()) {// 当运行 休息 1000秒
usleep(1000);
}
if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) {
throw new \RuntimeException(sprintf('The process has been signaled with signal "%s".', $this->processInformation['termsig']));
}//终止进程
return $this->exitcode;// 终止完成
}
[李景山php]每天TP5-20170121|thinkphp5-Process.php-3
最新推荐文章于 2023-06-10 13:11:51 发布