asynchronous php, How do fiber work in php?

67 views Asked by At

i m trying to understand how to use fiber as async for php : https://www.php.net/manual/fr/language.fibers.php

But i ve a probleme, is that is possible to run asynchronous ? Because i try multiple time to execute multiple fiber instance with no asynchronous success

I have this following code (Thanks to Ali Madadi for providing note in doc) But the fiber code have the same execution time than the classique code.

declare(ticks=1);

class Thread {
    
  protected $names = [];
  protected $fibers = [];
  protected $params = [];

  public function register(string|int $name, callable $callback, array $params)
  {
    $this->names[]  = $name;
    $this->fibers[] = new Fiber($callback);
    $this->params[] = $params;
  }

  public function run() {
    $output = [];

    while ($this->fibers) {

        foreach ($this->fibers as $i => $fiber) {
            try {
                if (!$fiber->isStarted()) {
                    $fiber->start(...$this->params[$i]);
                } elseif ($fiber->isTerminated()) {
                    $output[$this->names[$i]] = $fiber->getReturn();
                    unset($this->fibers[$i]);
                } elseif ($fiber->isSuspended()) {
                    $fiber->resume();
                }                
            } catch (Throwable $e) {
                $output[$this->names[$i]] = $e;
            }
        }

    }

    return $output;
  }

}

?>

And here is an example code on how to use above Thread class: <br/>

<?php

// testing function
function thread (string $print, int $loop)
{

  $i = $loop;
  while ($i--){
    $y = $loop;
    while ($y--) {
        // echo $y;
    }
  }

  return "Thread '{$print}' finished after printing '{$print}' for {$loop} times!";
}

$loopTime = 2000;




// sync process

$time_start = microtime(true);

foreach (range('A', 'Z') as $c) {
    thread($c, $loopTime);
}

$time_end = microtime(true);


$time = $time_end - $time_start;
echo "-Sync Process Time: {$time} <br/>";




// async process

$time_start = microtime(true);

$thread = new Thread();

foreach(range('A', 'Z') as $c) {
  $thread->register($c, 'thread', [$c, $loopTime]);
}

$outputs = $thread->run();

$time_end = microtime(true);


$time = $time_end - $time_start;
echo "Async Process Time: {$time} <br/>";

Is that normal ? Did i missunderstrand anything ? or is it the normal process of fiber ?

Thank you in advance for your help.

Edit : I think i have missunderstoud the working of Fiber, but based on this comment in the doc :

Here is a simple scheduler and thread pool that implements multithreading using fibers and tick functions in PHP 8.1 and returns the return value of each function in the pool in an array at the end.

Note that due to some bugs, you need to register a new tick function for each "thread". Remember to unregister all of them at the end.

The link bellow is the discussion on a bug that is going on right now (At the time of writing this). Note that based on the discussion, the ability to call Fiber::suspend() inside tick function may become forbidden in PHP 8.2+. But if the bug gets fixed, you can move register_tick_function() line to the top of the class, and this simple multithreading class in pure PHP code will work like a charm.
https://github.com/php/php-src/issues/8960

It could be possible to create async php system ?

0

There are 0 answers