505 votes

Comment peut-on utiliser le multi threading dans des applications PHP

Est-il un moyen réaliste de la mise en œuvre d'un multi-modèle de thread en PHP si vraiment, ou tout simplement de la simulation. Il y a quelque temps il a été suggéré que vous pourriez forcer le chargement du système d'exploitation à une autre instance de l'exécutable PHP et gérer d'autres processus simultanés.

Le problème avec cela est que lorsque le code PHP fin de l'exécution de PHP instance reste en mémoire, car il n'y a aucun moyen de le tuer de l'intérieur PHP. Donc si vous êtes à la simulation de plusieurs threads, vous pouvez imaginer ce qui va se passer. Donc, je suis toujours à la recherche d'un mode multi-threading qui peut être fait ou simulées de façon efficace au sein de PHP. Des idées?

508voto

Baba Points 49157

Le Multi-threading est possible en php

Oui, vous pouvez le faire multi-threading in PHP avec pthreads

D' PHP DOC

pthreads est une API Orientée Objet qui permet à l'utilisateur de terres multi-threading en PHP. Il inclut tous les outils dont vous avez besoin pour créer des applications multi-tâches ciblées sur le Web ou de la Console. Les applications PHP peuvent créer, lire, écrire, exécuter et de les synchroniser avec les Threads, les Travailleurs et Empilables.

Test Simple

#!/usr/bin/php
<?php
class AsyncOperation extends Thread {

    public function __construct($arg) {
        $this->arg = $arg;
    }

    public function run() {
        if ($this->arg) {
            $sleep = mt_rand(1, 10);
            printf('%s: %s  -start -sleeps %d' . "\n", date("g:i:sa"), $this->arg, $sleep);
            sleep($sleep);
            printf('%s: %s  -finish' . "\n", date("g:i:sa"), $this->arg);
        }
    }
}

// Create a array
$stack = array();

//Iniciate Miltiple Thread
foreach ( range("A", "D") as $i ) {
    $stack[] = new AsyncOperation($i);
}

// Start The Threads
foreach ( $stack as $t ) {
    $t->start();
}

?>

La Première Exécution

12:00:06pm:     A  -start -sleeps 5
12:00:06pm:     B  -start -sleeps 3
12:00:06pm:     C  -start -sleeps 10
12:00:06pm:     D  -start -sleeps 2
12:00:08pm:     D  -finish
12:00:09pm:     B  -finish
12:00:11pm:     A  -finish
12:00:16pm:     C  -finish

Deuxième Manche

12:01:36pm:     A  -start -sleeps 6
12:01:36pm:     B  -start -sleeps 1
12:01:36pm:     C  -start -sleeps 2
12:01:36pm:     D  -start -sleeps 1
12:01:37pm:     B  -finish
12:01:37pm:     D  -finish
12:01:38pm:     C  -finish
12:01:42pm:     A  -finish

L'Exemple Du Monde Réel

error_reporting(E_ALL);
class AsyncWebRequest extends Thread {
    public $url;
    public $data;

    public function __construct($url) {
        $this->url = $url;
    }

    public function run() {
        if (($url = $this->url)) {
            /*
             * If a large amount of data is being requested, you might want to
             * fsockopen and read using usleep in between reads
             */
            $this->data = file_get_contents($url);
        } else
            printf("Thread #%lu was not provided a URL\n", $this->getThreadId());
    }
}

$t = microtime(true);
$g = new AsyncWebRequest(sprintf("http://www.google.com/?q=%s", rand() * 10));
/* starting synchronized */
if ($g->start()) {
    printf("Request took %f seconds to start ", microtime(true) - $t);
    while ( $g->isRunning() ) {
        echo ".";
        usleep(100);
    }
    if ($g->join()) {
        printf(" and %f seconds to finish receiving %d bytes\n", microtime(true) - $t, strlen($g->data));
    } else
        printf(" and %f seconds to finish, request failed\n", microtime(true) - $t);
}

64voto

masterb Points 99

pourquoi n'utilisez-vous pas popen?

for ($i=0; $i<10; $i++) {
    // open ten processes
    for ($j=0; $j<10; $j++) {
        $pipe[$j] = popen('script2.php', 'w');
    }

    // wait for them to finish
    for ($j=0; $j<10; ++$j) {
        pclose($pipe[$j]);
    }
}

29voto

Ricardo Points 1

Le filetage n'est pas disponible en stock en PHP, mais la programmation simultanée est possible à l'aide de requêtes HTTP asynchrones des appels.

Avec la boucle du paramètre de délai d'attente fixé à 1 et en utilisant la même session_id pour le processus que vous souhaitez être associés les uns avec les autres, vous pouvez communiquer avec les variables de session comme dans mon exemple ci-dessous. Avec cette méthode, vous pouvez même fermer votre navigateur et le processus concurrent existe toujours sur le serveur.

N'oubliez pas de vérifier la bonne ID de session comme ceci:

http://localhost/test/verifysession.php?sessionid=[id]

startprocess.php

$request = "http://localhost/test/process1.php?sessionid=".$_REQUEST["PHPSESSID"];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_exec($ch);
curl_close($ch);
echo $_REQUEST["PHPSESSID"];

process1.php

set_time_limit(0);

if ($_REQUEST["sessionid"])
   session_id($_REQUEST["sessionid"]);

function checkclose()
{
   global $_SESSION;
   if ($_SESSION["closesession"])
   {
       unset($_SESSION["closesession"]);
       die();
   }
}

while(!$close)
{
   session_start();
   $_SESSION["test"] = rand();
   checkclose();
   session_write_close();
   sleep(5);
}

verifysession.php

if ($_REQUEST["sessionid"])
    session_id($_REQUEST["sessionid"]);

session_start();
var_dump($_SESSION);

closeprocess.php

if ($_REQUEST["sessionid"])
    session_id($_REQUEST["sessionid"]);

session_start();
$_SESSION["closesession"] = true;
var_dump($_SESSION);

17voto

J.D. Fitz.Gerald Points 1421

Si vous ne pouvez pas le fil, vous avez un certain degré de contrôle de processus en php. Les deux jeux de fonctions qui sont utiles sont ici:

Fonctions de gestion des processus http://www.php.net/manual/en/ref.pcntl.php

Les fonctions POSIX http://www.php.net/manual/en/ref.posix.php

Vous pourriez fourche votre processus avec pcntl_fork - retour du PID de l'enfant. Ensuite, vous pouvez utiliser posix_kill à despose de ce PID.

Cela dit, si vous tuez un processus parent d'un signal doit être envoyé pour le processus de l'enfant en lui disant d'en mourir. Si php n'est pas reconnaissant de ce que vous pourriez enregistrer une fonction de gérer et de faire un nettoyage de sortie à l'aide de pcntl_signal.

13voto

p.vansia Points 335

à l'aide de threads est rendue possible par la pthreads extension PECL

http://www.php.net/manual/en/book.pthreads.php

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X