Tuckbros
Tuckbros

Reputation: 437

How to externalize function for parallel processing in PHP

I am going to play with parallel processing in PHP. https://www.php.net/manual/en/book.parallel.php

I could make something very basic to understand the main concept.

Here is where I am :

 <?php
for ($i = 0; $i < 7; $i++) {
    $runtime = new \parallel\Runtime();
    $runtimes[] = $runtime;
    echo "starting thread $i from main thread" . PHP_EOL;
    $future = $runtime->run(function($i){
        $nbtot = 0;
        echo "I am thread $i " . PHP_EOL;
        for ($j = 0; $j < 5; $j++) {
            echo "thread $i in loop $j " . PHP_EOL;
            $nbsec = rand(0, 10);
            $nbtot = $nbtot + $nbsec;
            sleep($nbsec);
        }
        return array($i, $nbtot); //returning an array to the main thread
    }, array($i)); //passing argument to the closure
    $futures[] = $future;
}
$ct = count($futures);
while ( $ct > 0 ) {
    echo "$ct active threads" . PHP_EOL;
    foreach ($futures as $key => $future) {
        if ($future->done()) {
            print_r($future->value());
            unset($futures[$key]);
        }
    }
    sleep(2);
    $ct = count($futures);
}
?>

For maintenance purpose, I would like to put the code of the function (closure) in another file. I guess that \parallel\bootstrap is made for it, but I can't figure out how to make it work. What should I change my current code ? and what should I place in the other file ?

Upvotes: 0

Views: 870

Answers (3)

JGO
JGO

Reputation: 11

It's possible to work with class inside the Closure function. For that, you need to use require_once inside the function to include them. It's probably possible to include the require_once outside the Closure function if you use a bootstrap

Upvotes: 0

Tuckbros
Tuckbros

Reputation: 437

After some hard time and the support of Joe Watkins, here is the answer I was looking for :

<?php
\parallel\bootstrap('test_threads_inc.php');
for ($i = 0; $i < 7; $i++) {
    echo "starting thread $i from main thread" . PHP_EOL;
    $futures[] = \parallel\run(function($a) {return myfunction($a);}, array($i)); //passing argument to the closure
}
$ct = count($futures);
while ( $ct > 0 ) {
    echo "$ct active threads" . PHP_EOL;
    foreach ($futures as $key => $future) {
        if ($future->done()) {
            print_r($future->value());
            unset($futures[$key]);
        }
    }
    sleep(2);
    $ct = count($futures);
}

?>

and test_threads_inc.php :

<?php

function myfunction($i) {
        $nbtot = 0;
        echo "I am thread $i " . PHP_EOL;
        for ($j = 0; $j < 5; $j++) {
            echo "thread $i in loop $j " . PHP_EOL;
            $nbsec = rand(0, 10);
            $nbtot = $nbtot + $nbsec;
            sleep($nbsec);
        }
        return array($i, $nbtot); //returning an array to the main thread
    }
?>

Upvotes: 1

Tuckbros
Tuckbros

Reputation: 437

I wrote this include file test_inc.php :

<?php
$myworker = function($i){
...
    return array($i, $nbtot); //returning an array to the main thread
}
?>

and then include it at the beginning of main script : include('test_inc.php');. I could replace the function description by the variable just like this : $future = $runtime->run($myworker, array($i));

Upvotes: 0

Related Questions