Ricerca…


Multiprocessing utilizzando le funzioni di fork integrate

È possibile utilizzare le funzioni integrate per eseguire i processi PHP come fork. Questo è il modo più semplice per ottenere un lavoro parallelo se non hai bisogno che i tuoi thread parlino tra loro.

Ciò consente di inserire attività a tempo elevato (come il caricamento di un file su un altro server o l'invio di un messaggio di posta elettronica) su un altro thread in modo che lo script venga caricato più rapidamente e possa utilizzare più core, ma si tenga presente che non si tratta di vero multithreading e il thread principale non sarà sapere cosa stanno facendo i bambini.

Nota che sotto Windows questo farà apparire un altro prompt dei comandi per ogni fork che avvii.

master.php

$cmd = "php worker.php 10";
if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') // for windows use popen and pclose
{
    pclose(popen($cmd,"r"));
}
else //for unix systems use shell exec with "&" in the end
{
    exec('bash -c "exec nohup setsid '.$cmd.' > /dev/null 2>&1 &"');
}

worker.php

//send emails, upload files, analyze logs, etc
$sleeptime = $argv[1];
sleep($sleeptime);

Creazione di processi figlio tramite fork

PHP ha costruito in funzione pcntl_fork per la creazione del processo figlio. pcntl_fork è uguale a fork in unix. Non contiene alcun parametro e restituisce numeri interi che possono essere utilizzati per differenziare tra processo padre e figlio. Si consideri il seguente codice per la spiegazione

<?php
    // $pid is the PID of child
    $pid = pcntl_fork();
    if ($pid == -1) {
         die('Error while creating child process');
    } else if ($pid) {
         // Parent process
    } else {
         // Child process
    }
?>

Come puoi vedere -1 è un errore nel fork e il bambino non è stato creato. Alla creazione di child, abbiamo due processi in esecuzione con PID separati.

Un'altra considerazione qui è un zombie process o un zombie process defunct process quando il processo genitore termina prima del processo figlio. Per evitare che i bambini zombi pcntl_wait($status) semplicemente aggiungi pcntl_wait($status) alla fine del processo genitore.

pnctl_wait sospende l'esecuzione del processo genitore fino all'uscita dal processo figlio.

Vale anche la pena notare che il zombie process non può essere ucciso usando il segnale SIGKILL .

Comunicazione tra processi

La comunicazione tra processi consente ai programmatori di comunicare tra diversi processi. Ad esempio, consideriamo la necessità di scrivere un'applicazione PHP in grado di eseguire comandi bash e stampare l'output. Useremo proc_open , che eseguirà il comando e restituirà una risorsa con cui possiamo comunicare. Il codice seguente mostra un'implementazione di base che esegue pwd in bash da php

<?php
    $descriptor = array(
        0 => array("pipe", "r"), // pipe for stdin of child
        1 => array("pipe", "w"), // pipe for stdout of child
    );
    $process = proc_open("bash", $descriptor, $pipes);
    if (is_resource($process)) {
        fwrite($pipes[0], "pwd" . "\n");
        fclose($pipes[0]);
        echo stream_get_contents($pipes[1]);
        fclose($pipes[1]);
        $return_value = proc_close($process);

    }
?>

proc_open esegue il comando bash con $descriptor come specifiche del descrittore. Successivamente utilizziamo is_resource per convalidare il processo. Una volta terminato, possiamo iniziare a interagire con il processo figlio usando $ pipe che viene generato secondo le specifiche del descrittore.

Successivamente, possiamo semplicemente usare fwrite per scrivere su stdin del processo figlio. In questo caso pwd seguito dal ritorno a capo. Infine stream_get_contents è usato per leggere lo stdout del processo figlio.

Ricordarsi sempre di chiudere il processo figlio utilizzando proc_close () che interromperà il figlio e restituirà il codice di stato di uscita.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow