La classe parallel\Runtime

(0.8.0)

Objets d'exécution

Chaque exécution représente un seul thread PHP, le thread est créé (et initialisé) lors de la construction. Le thread attend ensuite que des tùches soient planifiées : les tùches planifiées seront exécutées FIFO puis le thread reprendra l'attente jusqu'à ce que d'autres tùches soient planifiées, ou qu'il soit fermé, tué ou détruit par les rÚgles de portée normales des objets PHP.

Avertissement

Lorsque qu'une exécution est détruite par les rÚgles de portée normales des objets PHP, elle exécutera d'abord toutes les tùches qui ont été planifiées, et bloquera pendant ce temps.

Amorçage d'exécution

Lorsqu'une nouvelle exĂ©cution est créée, elle ne partage pas de code avec le thread (ou le processus) qui l'a créée. Cela signifie qu'elle n'a pas les mĂȘmes classes et fonctions chargĂ©es, ni le mĂȘme chargeur automatique dĂ©fini. Dans certains cas, une exĂ©cution trĂšs lĂ©gĂšre est souhaitable car les tĂąches qui seront planifiĂ©es n'ont pas besoin d'accĂ©der au code du thread parent. Dans les cas oĂč les tĂąches ont besoin d'accĂ©der au mĂȘme code, il suffit de dĂ©finir un chargeur automatique comme amorçage.

Note: Le prĂ©chargement peut ĂȘtre utilisĂ© en conjonction avec parallel, dans ce cas le code prĂ©chargĂ© est disponible sans amorçage

Synopsis de la classe

final class parallel\Runtime {
/* Créer */
public function __construct()
public function __construct(string $bootstrap)
/* Exécuter */
public function run(Closure $task): ?Future
public function run(Closure $task, array $argv): ?Future
/* Joindre */
public function close(): void
public function kill(): void
}

Sommaire

add a note

User Contributed Notes 4 notes

up
22
Luciano Vettoretti ¶
6 years ago
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();
}
up
5
gam6itko ¶
4 years ago
<?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";
up
0
Mikhail Streltsov (admin at my-fantasy dot ru) ¶
2 years ago
new Runtime()  will reset some basic (before number 10+-) Linux signal. 

If you already set handle of signal by pcntl_signal function - you need do it again
up
0
gam6itko ¶
4 years ago
<?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;