当前位置 : 主页 > 网络编程 > PHP >

Closure 任务管理,可以控制Closure超时时间

来源:互联网 收集:自由互联 发布时间:2021-06-28
Closure 任务管理,可以控制Closure超时时间 closureCollection = $closureCollection; $this-timeout = $timeout; } /** * 运行子进程 * * @param bool $isTimeout 任务是否会超时 * @throws \Exception */ public function run($i
Closure 任务管理,可以控制Closure超时时间
 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);
        }
    }
}
网友评论