pcntlModule (not supported on non-UNIX systems)

A simple PHP multiprocess example might look like this:

// 5 subprocesses process tasks
for ($i = 0; $i < 5; $i{+ +)$pid = pcntl_fork();
    if ($pid= = -1) {
        die("could not fork");
    } elseif ($pid) {
        echo "I'm the Parent $i\n";
    } else { // Child processing
        echo "I'm the Child $i\n";
        // Business processing
        exit($i); // It is important to exit the child process, otherwise pcntl_fork() will cause the process to fork again.}}// Wait for the child process to finish executing
while (pcntl_waitpid(0.$status) != -1) {
    $status = pcntl_wexitstatus($status);
    echo "Child $status completed\n";
}
Copy the code

Of course, in practice we can not output code like this, not robust, not elegant, so I found an extension package based on PCNTL package to use.

spatie/async- based onpcntlEncapsulated extension packages

Here is an example of how I used Spatie/Async to optimize a multi-process request

The original code (about 20 seconds) – github.com/guanguans/m…

/ * * *@param string $keyword
 *
 * @return array
 */
public function searchAll(string $keyword) :array
{
    $songAll = [];

    foreach ($this->platforms as $platform) {
        $songAll = array_merge($songAll.$this->search($platform.$keyword));
    }

    return $songAll;
}

/ * * *@param string $platform
 * @param string $keyword
 *
 * @return mixed
 */
public function search(string $platform.string $keyword)
{
    $meting = $this->getMeting($platform);

    $songs = json_decode($meting->format()->search($keyword), true);

    foreach ($songs as $key= > &$song) {
        $detail = json_decode($meting->format()->url($song['url_id']), true);
        if (empty($detail['url']) {unset($songs[$key]);
        }
        $song = array_merge($song.$detail);
    }
    unset($song);

    return $songs;
}
Copy the code

After improvement (take about 4s) – github.com/guanguans/m…

/ * * *@param string $keyword
 *
 * @return array
 */
public function searchAll(string $keyword) :array
{
    $songAll = [];
    $pool = Pool::create();
    foreach ($this->platforms as $platform) {
        $pool->add(function () use ($platform.$keyword) {
            return $this->search($platform.$keyword);
        }, $this->getSerializedOutput())->then(function ($output) use (&$songAll) {
            $songAll = array_merge($songAll.$output);
        })->catch(function (\Throwable $exception) {
            exit($exception->getMessage());
        });
    }
    $pool->wait();

    return $songAll;
}

/ * * *@return mixed
 */
public function search(string $platform.string $keyword)
{
    $meting = $this->getMeting($platform);
    $songs = json_decode($meting->format()->search($keyword), true);

    $pool = Pool::create();
    foreach ($songs as $key= > &$song) {
        $pool->add(function () use ($meting.$song) {
            return json_decode($meting->format()->url($song['url_id']), true);
        })->then(function ($output) use (&$songs, &$song.$key) {
            $song = array_merge($song.$output);
            if (empty($song['url']) {unset($songs[$key]);
            }
        })->catch(function (\Throwable $exception) {
            exit($exception->getMessage());
        });
    }
    unset($song);
    $pool->wait();

    return $songs;
}
Copy the code

A link to the

  • www.php.net/manual/zh/b…
  • Github.com/spatie/asyn…
  • Github.com/guanguans/m…

The original link

  • Github.com/guanguans/g…