The parallel\Runtime class

(0.8.0)

Runtime Objects

Each runtime represents a single PHP thread, the thread is created (and bootstrapped) upon construction. The thread then waits for tasks to be scheduled: Scheduled tasks will be executed FIFO and then the thread will resume waiting until more tasks are scheduled, or it's closed, killed, or destroyed by the normal scoping rules of PHP objects.

Warning

When a runtime is destroyed by the normal scoping rules of PHP objects, it will first execute all of the tasks that were scheduled, and block while doing so.

Runtime Bootstrapping

When a new runtime is created, it does not share code with the thread (or process) that created it. This means it doesn't have the same classes and functions loaded, nor the same autoloader set. In some cases, a very lightweight runtime is desirable because the tasks that will be scheduled do not need access to the code in the parent thread. In those cases where the tasks do need to access the same code, it is enough to set an autoloader as the bootstrap.

Note:

preloading may be used in conjunction with parallel, in this case preloaded code is available without bootstrapping

类摘要

final parallel\Runtime {
/* Create */
public __construct ( )
public __construct ( string $bootstrap )
/* Execute */
public run ( Closure $task ) : Future|null
public run ( Closure $task , array $argv ) : Future|null
/* Join */
public close ( ) : void
public kill ( ) : void
}

Table of Contents

User Contributed Notes

gam6itko 10-Sep-2021 05:54
<?php

// make sure that is really parallel execution (showcase2).
// Then you use echo within task-function there is a real chance that the application will hang.
// We should control Futures to avoid this behaviour.
// You will get different output on each execution.

use parallel\{Future, Runtime};

const
THREADS_COUNT = 10;
const
THREADS_I_MAX = 100;

// executed within thread
$task = static function (int $i, int $to): void {
    echo
"[enter$i]";
    for (
$j = 0; $j < $to; $j++) {
        echo
$i;
    }
    echo
"[exit$i]";
};

// creating a few threads
$runtimeList = [];
for (
$i = 0; $i < THREADS_COUNT; $i++) {
   
$runtimeList[] = new Runtime();
}
// run all threads
$futureList = [];
foreach (
$runtimeList as $i => $runtime) {
    echo
"[run$i]";
   
$futureList[] = $runtime->run($task, [$i, THREADS_I_MAX]);
}

// waiting until all threads are done
// if you delete code bellow then your script will hang
do {
   
usleep(1);
   
$allDone = array_reduce(
       
$futureList,
        function (
bool $c, Future $future): bool {
            return
$c && $future->done();
        },
       
true
   
);
} while (
false === $allDone);
echo
"done\n";
gam6itko 10-Sep-2021 04:58
<?php

// make sure that is really parallel execution
// you will get different output on each script run

use parallel\{Channel, Runtime};

const
THREADS_COUNT = 5;
const
THREADS_I_MAX = 10;

$ch = new Channel();

// executed within thread
$task = static function (Channel $ch, int $i, int $to): void {
    echo
"[enter: $i]\n";
    for (
$j = 0; $j < $to; $j++) {
       
$ch->send($i);
    }
    echo
"[exit: $i]\n";
};

// creating a few threads
$runtimeList = [];
for (
$i = 0; $i < THREADS_COUNT; $i++) {
   
$runtimeList[] = new Runtime();
}
// run all threads
foreach ($runtimeList as $i => $runtime) {
    echo
"[run: $i]\n";
   
$runtime->run($task, [$ch, $i, THREADS_I_MAX]);
}

// reading messages from channel
$queue = '';
for (
$i = 0; $i < THREADS_COUNT * THREADS_I_MAX; $i++) {
   
$queue .= $ch->recv();
}
$ch->close();

echo
$queue . PHP_EOL;
Luciano Vettoretti 25-Nov-2019 08:27
basic-multithreading-test.php

<?php
use parallel\Runtime;
use
parallel\Channel;

$test = "this var is not accesible in a thread";

// this function will be the threads
$thread_function = function (int $id, Channel $ch) {
   
// delay the first thread to simulate better multithreading
    // second thread always finishes first
   
$sleep = ($id == 2) ? 1 : 2;
   
sleep($sleep);

   
// print thread id
    // so it's clear second thread goes first
    // and also you can make sure multithreading is working
   
var_dump("thread $id sleep $sleep");

   
// try to capture globals, but it's not possible
   
echo '$GLOBALS["test"] = ';
    @
var_dump($GLOBALS["test"]);

   
// the only way to share data is between channels
   
$ch->send($sleep);
};

try {
   
// each runtime represents a thread
   
$r1 = new Runtime();
   
$r2 = new Runtime();

   
// channel where the date will be sharead
   
$ch1 = new Channel();

   
// args that will be sent to $thread_function
   
$args = array();
   
$args[0] = null;
   
$args[1] = $ch1;

   
// running thread 1
   
$args[0] = 1;
   
$r1->run($thread_function, $args);

   
// running thread 2
   
$args[0] = 2;
   
$r2->run($thread_function, $args);

   
// receive data from channel
   
$x = $ch1->recv();
   
$y = $ch1->recv();

   
// close channel
   
$ch1->close();

    echo
"\nData received by the channel: $x and $y";
} catch (
Error $err) {
    echo
"\nError:", $err->getMessage();
} catch (
Exception $e) {
    echo
"\nException:", $e->getMessage();
}
PHP8中文手册 站长在线 整理 版权归PHP文档组所有