wait child exit.
@param  callable $onExit
@return bool
506139
public static function wait(callable $onExit)
    {
        $status = null;

        //pid<0：子进程都没了
        //pid>0：捕获到一个子进程退出的情况
        //pid=0：没有捕获到退出的子进程
        while (($pid = pcntl_waitpid(-1, $status, WNOHANG)) >= 0) {
            if ($pid) {
                // ... (callback, pid, exitCode, status)
                $onExit($pid, pcntl_wexitstatus($status), $status);
            } else {
                usleep(50000);
            }
        }

        return true;
    }
745291
public function kill(int $pid, bool $wait = false): bool
    {
        return $this->process->kill($pid, $wait);
    }
2211
public function coroutineSend($send, $oneway = false, callable $set = null)
    {
        return Pool::getInstance()->get(TcpClientRequestCoroutine::class)->init($this, $send, $oneway, $set);
    }
382378
private function childProcessStatus($status) {
        switch (true) {
            case pcntl_wifexited($status):
                $code = pcntl_wexitstatus($status);
                if (($res = $this->handleProcessExitStatus($this->childPID, self::PROCESS_TYPE_JOB, $code)) !== false) {
                    $this->job->fail('system:fatal', $res);
                }
                return true;

            case pcntl_wifsignaled($status):
                $sig = pcntl_wtermsig($status);
                if ($sig !== SIGKILL) {
                    $this->childProcessUnhandledSignal($sig);
                }
                return true;

            case pcntl_wifstopped($status):
                $sig = pcntl_wstopsig($status);
                $this->logger->info(sprintf("child %d was stopped with signal %s\n", $this->childPID, pcntl_sig_name($sig)));
                return false;

            default:
                $this->logger->error(sprintf("unexpected status for child %d; exiting\n", $this->childPID));
                exit(1);
        }
    }
803756
public function inputObserver($callback, $exitCicle = null)
    {
        if (self::isCli() === false || is_callable($callback) === false) {
            return false;
        }

        $this->io = $callback;
        $this->ec = $exitCicle ? $exitCicle : $this->ec;

        if ($this->started) {
            return true;
        }

        $this->started = true;
        $this->fireInputObserver();

        return true;
    }
1269930
public function onChildProcessExit($exitCode, $termSignal)
    {
        $this->logger->error(sprintf('Child process exited. (Code: %d, Signal: %d)', $exitCode, $termSignal));
        $this->monitorChildProcesses();
    }
954281
private function killKeepTransactionAlive() {
        if ($this->txProcPid > 0) {
            posix_kill($this->txProcPid, \SIGKILL);
            $status          = null;
            pcntl_wait($status);
            $this->txProcPid = null;
        }
        if ($this->txProc) {
            $this->txProc = null;
        }
    }
672713
static function Redirect($target, $redirectHeader = "", $noExit = false)
    {
        session_write_close();
        if ($redirectHeader)
        {
            header($redirectHeader);
        }
        header("Location: ". $target);
        if (!$noExit)
        {
            exit();
        }
    }
649754
public static function killAndWait(
        int $pid,
        &$error = null,
        $name = 'process',
        bool $force = false,
        int $waitTime = 10
    ): bool {
        // do stop
        if (!self::kill($pid, $force)) {
            $error = "Send stop signal to the $name(PID:$pid) failed!";

            return false;
        }

        // not wait, only send signal
        if ($waitTime <= 0) {
            $error = "The $name process stopped";

            return true;
        }

        $startTime = \time();
        echo 'Stopping .';

        // wait exit
        while (true) {
            if (!self::isRunning($pid)) {
                break;
            }

            if (\time() - $startTime > $waitTime) {
                $error = "Stop the $name(PID:$pid) failed(timeout)!";
                break;
            }

            echo '.';
            sleep(1);
        }

        if ($error) {
            return false;
        }

        return true;
    }
725013
public function isAsync($async = null)
    {
        if ($async !== null) {
            $this->async = (bool) $async;
        }

        return $this->async;
    }
273832
private static function waitChildProcess(string $name, $boot)
    {
        /* @var \Swoft\Process\ProcessInterface $processObject */
        $processObject = App::getBean($name);
        if (($hasWait = method_exists($processObject, 'wait')) || $boot) {
            Process::signal(SIGCHLD, function($sig) use ($name, $processObject, $hasWait) {
                while($ret =  Process::wait(false)) {
                    if ($hasWait) {
                        $processObject->wait($ret);
                    }

                    unset(self::$processes[$name]);
                }
            }); 
        }
    }
1039205
public function waitForVisibleText($text)
    {
        $this->waitFor(function ($context) use ($text) {
            try {
                /** @var Web $context */
                $context->assertPageContainsText($text);
                return true;
            } catch (ResponseTextException $e) {

            }
        });
    }
367886
public function send($exit = true)
    {
        $response = $this->getResponse();

        $this->sendHeaders($response);
        $this->sendBody($response->getBody());

        if (true === $exit) {
            exit;
        }
    }
647831
public function wait(): bool
    {
        if (!$this->pid) {
            throw new BadMethodCallException('wait can only be called from the parent of a forked process');
        }

        // Cascade the call to waitAll for asynchronous processes
        if ($this->async) {
            return $this->waitAll();
        }

        // Wait for the process to complete
        pcntl_waitpid($this->pid, $status);

        // Capture any messages returned by the child process
        if ($msg = $this->channel->receive()) {
            $this->messages[] = $msg;
        }

        // If the process did not exit gracefully, mark it as failed
        if (!pcntl_wifexited($status)) {
            return false;
        }

        // If the process exited gracefully, check the exit code
        return pcntl_wexitstatus($status) === 0;
    }
52736
public function wait($pid = null)
    {
        if ($pid) {
            $threads = [$pid];
        } else {
            $threads = $this->threads;
        }

        $error = false;
        $status = 0;
        foreach ($threads as $pid) {
            pcntl_waitpid($pid, $status);
            if ($status > 0) {
                $error = $status;
            }
            unset($this->threads[$pid]);
        }

        if (!$this->ignoreErrors && $error) {
            $memory = shmop_open($this->memoryKey, "a", 0, 0);
            $errors = shmop_read($memory, 0, static::SHARED_MEMORY_LIMIT);
            shmop_delete($memory);
            shmop_close($memory);

            $error = "An error occurred within a thread, the return code was (" . $error . ")";
            if ($errors = trim($errors)) {
                $error .= "\n" . $errors;
            }
            throw new \Exception($error);
        }

        return $status;
    }
1183699
public function lock($taskCallable = null, $afterLockCallable = null)
    {
        if($this->isLocked())
        {
            return false;
        }
        if(!$this->__lock())
        {
            return false;
        }
        if(null === $taskCallable)
        {
            return true;
        }
        else
        {
            try {
                if(null !== $afterLockCallable && true === $afterLockCallable())
                {
                    return true;
                }
                $taskCallable();
                return true;
            } catch (\Throwable $th) {
                throw $th;
            } finally {
                $this->unlock();
            }
        }
    }
864943
private function waitForStreamActivity($timeout)
    {
        $read  = $this->readStreams;
        $write = $this->writeStreams;

        if ($this->streamSelect($read, $write, $timeout) === false)
        {
            return;
        }

        foreach ($read as $stream)
        {
            $key = (int) $stream;

            if (isset($this->readListeners[$key]))
            {
                $callable = $this->readListeners[$key];
                $callable($stream, $this);
            }
        }

        foreach ($write as $stream)
        {
            $key = (int) $stream;

            if (isset($this->writeListeners[$key]))
            {
                $callable = $this->writeListeners[$key];
                $callable($stream, $this);
            }
        }
    }