Szukaj…


Wieloprocesorowość za pomocą wbudowanych funkcji widelca

Możesz używać wbudowanych funkcji do uruchamiania procesów PHP jako widelców. Jest to najprostszy sposób na osiągnięcie pracy równoległej, jeśli nie potrzebujesz, aby twoje wątki ze sobą rozmawiały.

Pozwala to na umieszczenie zadań wymagających dużej ilości czasu (takich jak przesyłanie pliku na inny serwer lub wysyłanie wiadomości e-mail) do innego wątku, dzięki czemu skrypt ładuje się szybciej i może korzystać z wielu rdzeni, ale należy pamiętać, że nie jest to prawdziwa wielowątkowość, a główny wątek nie wiedzieć, co planują dzieci.

Pamiętaj, że w systemie Windows spowoduje to pojawienie się kolejnego wiersza polecenia dla każdego uruchamianego rozwidlenia.

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

Tworzenie procesu potomnego za pomocą widelca

PHP ma wbudowaną funkcję pcntl_fork do tworzenia procesu potomnego. pcntl_fork jest taki sam jak fork w pcntl_fork . Nie przyjmuje żadnych parametrów i zwraca liczbę całkowitą, której można użyć do rozróżnienia procesu nadrzędnego i podrzędnego. Wyjaśnij następujący kod

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

Jak widać -1 oznacza błąd w rozwidleniu i dziecko nie zostało utworzone. Po utworzeniu dziecka mamy dwa procesy działające z oddzielnym PID .

Inną kwestią jest zombie process lub defunct process gdy proces macierzysty kończy się przed procesem potomnym. Aby zapobiec procesowi pcntl_wait($status) zombie, po prostu dodaj pcntl_wait($status) na końcu procesu nadrzędnego.

pnctl_wait zawiesza wykonywanie procesu macierzystego, dopóki proces potomny nie zakończy działania.

Warto również zauważyć, że zombie process nie może zostać zabity za pomocą sygnału SIGKILL .

Komunikacja międzyprocesowa

Komunikacja międzyprocesowa umożliwia programistom komunikację między różnymi procesami. Rozważmy na przykład, że musimy napisać aplikację PHP, która może uruchamiać polecenia bash i drukować dane wyjściowe. Będziemy używać proc_open , który wykona polecenie i zwróci zasób, z którym możemy się komunikować. Poniższy kod pokazuje podstawową implementację, która uruchamia pwd w bash z 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 uruchamia polecenie bash z $descriptor jako specyfikacją deskryptora. Następnie używamy is_resource do sprawdzenia poprawności procesu. Po zakończeniu możemy rozpocząć interakcję z procesem potomnym za pomocą $ pipe, który jest generowany zgodnie ze specyfikacjami deskryptora.

Następnie możemy po prostu użyć fwrite aby napisać do standardowego procesu potomnego. W tym przypadku pwd po którym następuje powrót karetki. Wreszcie stream_get_contents służy do odczytu standardowego procesu potomnego.

Zawsze pamiętaj, aby zamknąć proces potomny za pomocą proc_close (), który zakończy dziecko i zwróci kod statusu wyjścia.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow