Zoeken…


Multiprocessing met ingebouwde vorkfuncties

U kunt ingebouwde functies gebruiken om PHP-processen als vorken uit te voeren. Dit is de meest eenvoudige manier om parallel werk te bereiken als u uw threads niet nodig hebt om met elkaar te praten.

Hiermee kunt u tijdintensieve taken (zoals het uploaden van een bestand naar een andere server of het verzenden van een e-mail) naar een andere thread zetten, zodat uw script sneller wordt geladen en meerdere cores kan gebruiken, maar houd er rekening mee dat dit geen echte multithreading is en uw hoofdthread niet weet wat de kinderen van plan zijn.

Merk op dat onder Windows hierdoor een nieuwe opdrachtprompt verschijnt voor elke vork die u start.

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);

Onderliggend proces maken met behulp van vork

PHP heeft de functie pcntl_fork voor het maken van een onderliggend proces. pcntl_fork is hetzelfde als fork in unix. Het neemt geen parameters op en retourneert een geheel getal dat kan worden gebruikt om onderscheid te maken tussen ouder- en kindproces. Overweeg de volgende code voor uitleg

<?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
    }
?>

Zoals je kunt zien, is -1 een fout in de vork en is het kind niet gemaakt. Bij het aanmaken van child hebben we twee processen die met een afzonderlijke PID .

Een andere overweging hier is een zombie process of een defunct process wanneer het ouderproces eindigt voordat het kindproces. Om een zombie-kinderproces te voorkomen, voegt u gewoon pcntl_wait($status) aan het einde van het ouderproces.

pnctl_wait schort de uitvoering van het bovenliggende proces op totdat het onderliggende proces is afgesloten.

Het is ook vermeldenswaard dat zombie process kan niet worden gedood met behulp van SIGKILL signaal.

Communicatie tussen processen

Interprocescommunicatie stelt programmeurs in staat om te communiceren tussen verschillende processen. Laten we bijvoorbeeld overwegen dat we een PHP-toepassing moeten schrijven die bash-opdrachten kan uitvoeren en de uitvoer kan afdrukken. We zullen proc_open , die de opdracht uitvoert en een bron retourneert waarmee we kunnen communiceren. De volgende code toont een basisimplementatie die pwd in bash vanaf php uitvoert

<?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 voert bash opdracht uit met $descriptor als descriptorspecificaties. Daarna gebruiken we is_resource om het proces te valideren. Eenmaal gedaan kunnen we beginnen met interactie met het onderliggende proces met behulp van $ pipes die wordt gegenereerd volgens de descriptorspecificaties.

Daarna kunnen we eenvoudig fwrite gebruiken fwrite te schrijven naar stdin of child-proces. In dit geval pwd gevolgd door koetsteruggave. Eindelijk wordt stream_get_contents gebruikt om stdout van child-proces te lezen.

Denk er altijd aan om het onderliggende proces te sluiten met proc_close () waarmee het kind wordt beëindigd en de exitstatuscode wordt geretourneerd.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow