Closure 任务管理,可以控制Closure超时时间 closureCollection = $closureCollection; $this-timeout = $timeout; } /** * 运行子进程 * * @param bool $isTimeout 任务是否会超时 * @throws \Exception */ public function run($i
closureCollection = $closureCollection; $this->timeout = $timeout; } /** * 运行子进程 * * @param bool $isTimeout 任务是否会超时 * @throws \Exception */ public function run($isTimeout = false) { // 检查 if (!$this->_checkRun()) { return true; } // 创建子进程执行任务 foreach ($this->closureCollection as $clousre) { $pid = pcntl_fork(); if ($pid === 0) { // 子进程执行 $clousre(); // 一定要终止子进程 exit(0); } else if ($pid > 0) { $tmp['pid'] = $pid; $tmp['startTime'] = microtime(true); $this->pidCollection [] = $tmp; } else { throw new \Exception("创建子进程失败"); } // 停止0.2s创建 usleep(200 * 1000); } // 是否需要管理超时进程 if ($isTimeout) { $this->_killTimeoutPids(); } } /** * 检查是否可以run * * @return bool */ private function _checkRun() { // closure集合为空不能run if (empty($this->closureCollection)) { return false; } return true; } /** * 杀死超时进程 */ private function _killTimeoutPids() { // 终止超时的子进程 while (true) { foreach ($this->pidCollection as $key => $pidArr) { // 如果超过超时时间,则终止 if (microtime(true) - $pidArr['startTime'] > $this->timeout) { posix_kill($pidArr['pid'], 9); unset($this->pidCollection[$key]); } } // 终止 if (empty($this->pidCollection)) { break; } // 1s检查一次 sleep(1); } } }