amphp / parallel

An advanced parallelization library for PHP, enabling efficient multitasking, optimizing resource use, and application responsiveness through multiple CPU threads.
MIT License
779 stars 64 forks source link

Hang when using ext-uv and JIT #188

Closed danog closed 10 months ago

danog commented 1 year ago

@trowski @kelunik encountering a weird hang when using amphp/parallel and (only when using) ext-uv with JIT, the following example gets stuck with 100% CPU usage on ubuntu 20.04 with the ondrej ppa repos:

test.php:

<?php

use Amp\Parallel\Worker\ContextWorkerPool;
use danog\PixyReproducer\TestTask;
use Revolt\EventLoop;

use function Amp\Future\await;

require 'vendor/autoload.php';

$pool = new ContextWorkerPool(1000);

$states = [];
$futures = [];
for ($x = 0; $x < ($argv[1] ?? 10); $x++) {
    echo "Starting $x...\n";
    $task = $pool->submit(new TestTask);
    $futures []= $task->getFuture();

    $channel = $task->getChannel();
    EventLoop::queue(function () use ($channel, &$states, $x) {
        while ($data = $channel->receive()) {
            if (isset($data['ok'])) {
                $states[$x] = $data['ok'];
            } else {
                var_dump($data);
            }
        }
    });
}

echo "Done!\n";

await($futures);

TestTask.php:

<?php

namespace danog\PixyReproducer;

use Amp\Cancellation;
use Amp\Parallel\Worker\Task;
use Amp\Sync\Channel;

use function Amp\delay;

class TestTask implements Task {

    /**
     * Executed when running the Task in a worker.
     *
     * @param Channel<TReceive, TSend> $channel Communication channel to parent process.
     * @param Cancellation $cancellation Tasks may safely ignore this parameter if they are not cancellable.
     *
     * @return TResult A specific type can (and should) be declared in implementing classes.
     */
    public function run(Channel $channel, Cancellation $cancellation): mixed
    {
        delay(100);
    }
}

Result:

Starting 1...
Starting 2...
Starting 3...
Starting 4...
Starting 5...
Starting 6...
Starting 7...
Starting 8...
Starting 9...
Starting 10...
Starting 11...
Starting 12...
Starting 13...
Starting 14...
Starting 15...
Starting 16...
Starting 17...
Starting 18...
^C <stuck>

The same example works fine on my arch machine for some reason.

danog commented 1 year ago

Also, the issue does not appear when starting say 15 workers instead of 20

danog commented 1 year ago

oh nevermind, it's yet another JIT issue :(

danog commented 1 year ago

Ref https://github.com/php/php-src/issues/12249

trowski commented 10 months ago

Closing, as this issue appears to have been fixed in php-src.