Heim  >  Artikel  >  Backend-Entwicklung  >  Eine vorläufige Studie zu mehreren Prozessen in PHP7

Eine vorläufige Studie zu mehreren Prozessen in PHP7

藏色散人
藏色散人nach vorne
2019-04-04 13:52:463358Durchsuche

Vorbereitung

Wir alle wissen, dass PHPs Umgang mit Multi-Parallelität hauptsächlich vom Multiprozess des Servers oder PHP-FPM abhängt Die Wiederverwendung ihrer Prozesse, aber auch die Implementierung mehrerer PHP-Prozesse ist von großer Bedeutung, insbesondere bei der Verarbeitung großer Datenmengen oder der Ausführung von Hintergrund-DEMON Daemon-Prozessen im Hintergrund-CLI-Modus. Es erübrigt sich zu erwähnen, dass mehrere Prozesse Vorteile bieten.

PHPs Multithreading wurde ebenfalls erwähnt, aber das Problem der gemeinsamen Nutzung und Zuweisung von Multithread-Ressourcen innerhalb des Prozesses ist schwer zu lösen. PHP verfügt auch über eine Multithreading-Erweiterung pthreads , diese gilt jedoch als instabil und erfordert eine Thread-sichere Umgebung, sodass sie nicht häufig verwendet wird.

In der Vergangenheit hat ein großer Meister in der PHP-Gruppe einmal darauf hingewiesen, dass, wenn Hintergrund-PHP vorankommen will, Multiprozesse vermieden werden müssen. Zufälligerweise verwendet der Daemon-Prozess im Unternehmen auch die Multiprozesse von PHP. Prozess, kombiniert mit den verschiedenen Informationen und Handbüchern von Gu Ge, habe ich endlich die Multiverarbeitung verstanden und eine kleine Demo geschrieben (implementiert auf einem Linux-System). Wenn es Fehler oder Auslassungen gibt, danke Ihnen, dass Sie sie erwähnt haben.

Um Multi-Processing in PHP zu implementieren, benötigen wir zwei Erweiterungen pcntl und posix. Die Installationsmethode wird hier nicht beschrieben.

In PHP verwenden wir pcntl_fork(), um mehrere Prozesse zu erstellen (bei der C-Sprachprogrammierung von *NIX-Systemen generieren vorhandene Prozesse neue Prozesse durch Aufrufen der Fork-Funktion). Der neue Prozess nach der Verzweigung wird zum untergeordneten Prozess, der ursprüngliche Prozess wird zum übergeordneten Prozess und der untergeordnete Prozess verfügt über eine Kopie des übergeordneten Prozesses. Beachten Sie hier:

• Der untergeordnete Prozess teilt das Programmtextsegment mit dem übergeordneten Prozess

• Der untergeordnete Prozess verfügt über eine Kopie des Datenraums sowie des Heaps und Stapels des übergeordneten Prozesses. Beachten Sie, dass dies der Fall ist eine Kopie, keine Freigabe

• Der übergeordnete Prozess und der untergeordnete Prozess führen den Programmcode nach der Verzweigung weiter aus

• Nach der Verzweigung, unabhängig davon, ob der übergeordnete Prozess oder der untergeordnete Prozess ausgeführt wird Erstens kann es nicht bestätigt werden, und es hängt von der Systemplanung ab (abhängig von der Überzeugung)

Hier wird gesagt, dass der untergeordnete Prozess eine Kopie des Datenraums, des Heaps und des Stapels des übergeordneten Prozesses hat Bei den meisten Implementierungen handelt es sich nicht um eine wirklich vollständige Kopie. Noch wichtiger ist, dass die COW-Technologie (Copy On Write) verwendet wird, um Speicherplatz zu sparen. Vereinfacht ausgedrückt: Wenn weder der übergeordnete Prozess noch der untergeordnete Prozess diese Daten, den Heap und den Stapel ändert, teilen sich der übergeordnete Prozess und der untergeordnete Prozess vorübergehend dieselben Daten, denselben Heap und denselben Stapel. Nur wenn der übergeordnete oder untergeordnete Prozess versucht, die Daten, den Heap und den Stapel zu ändern, wird ein Kopiervorgang ausgeführt. Dies wird als Kopieren beim Schreiben bezeichnet.

Nach dem Aufruf von pcntl_fork() gibt die Funktion zwei Werte zurück. Gibt die Prozess-ID des untergeordneten Prozesses im übergeordneten Prozess und die Zahl 0 im untergeordneten Prozess selbst zurück. Da in der Apache- oder FPM-Umgebung mehrere Prozesse nicht ordnungsgemäß ausgeführt werden können, müssen Sie den Code in der PHP-CLI-Umgebung ausführen.

Erstellen eines Unterprozesses

Das Erstellen eines PHP-Unterprozesses ist der Beginn mehrerer Prozesse. Wir benötigen die Funktion pcntl_fork()

ausführliche Erklärung der Fork-Funktion

– Erzeugen Sie einen Zweig (untergeordneten Prozess) an der aktuellen Position des aktuellen Prozesses. Nachdem diese Funktion einen neuen untergeordneten Prozess erstellt hat, erbt der untergeordnete Prozess den aktuellen Kontext des übergeordneten Prozesses und führt die Ausführung von der pcntl_fork()  -Funktion nach unten wie der übergeordnete Prozess fort, mit der Ausnahme, dass der erhaltene Rückgabewert von pcntl_fork() unterschiedlich ist. Daher können wir den übergeordneten Prozess und den untergeordneten Prozess anhand des Rückgabewerts unterscheiden und dem übergeordneten Prozess und dem untergeordneten Prozess unterschiedliche logische Verarbeitungen zuweisen. pcntl_fork()

Wenn die Funktion pcntl_fork() erfolgreich ausgeführt wird, gibt sie die Prozess-ID (PID) des untergeordneten Prozesses im übergeordneten Prozess zurück, da die PID des anfänglichen Prozesses des Systems 1 ist, die PID von Die nachfolgenden Prozesse sind größer als dieser Prozess. Wir können also bestätigen, dass der aktuelle Prozess der übergeordnete Prozess ist, indem wir beurteilen, ob der Rückgabewert von pcntl_fork() im untergeordneten Prozess größer als 1 ist ein fester Wert von 0. Wir können auch beurteilen, dass der Rückgabewert von pcntl_fork() 0 ist. Um den untergeordneten Prozess zu bestimmen, wenn die Ausführung der Funktion pcntl_fork() fehlschlägt, gibt er natürlich -1 im übergeordneten Prozess zurück Es wird kein untergeordneter Prozess generiert.

Fork-Prozessinstanz

Fork-Kindprozess

$ppid = posix_getpid();
$pid = pcntl_fork();
if ($pid == -1) {
    throw new Exception('fork child process fail');
} elseif ($pid > 0) {
    cli_set_process_title("我是父 process,pid is : {$ppid}.");
    sleep(30);
} else {
    $cpid = posix_getpid();
    cli_set_process_title("我是 {$ppid} 子的 process,我的 process pid is : {$cpid}.");
    sleep(30);
}

Beschreibung:

posix_getpid(): Gibt die aktuelle Prozess-ID zurück

cli_set_process_title('Prozessname'): Geben Sie dem aktuellen Prozess einen lauten Namen.

Wenn wir dieses Beispiel ausführen, können wir die aktuellen beiden PHP-Prozesse sehen.

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ ps aux|grep -v grep |grep 我
www      18026  0.5  1.2 204068 25772 pts/0    S+   14:08   0:00 我是父 process,pid is : 18026.
www      18027  0.0  0.3 204068  6640 pts/0    S+   14:08   0:00 我 18026 子的 process,我的 process pid is : 18027. 

Der erste Abschnitt des Codes: Nachdem das Programm von pcntl_fork() gestartet wurde, führen der übergeordnete Prozess und der untergeordnete Prozess weiterhin den Code aus:

$pid = pcntl_fork();
if( $pid > 0 ){
  echo "我是父亲".PHP_EOL;
} else if( 0 == $pid ) {
  echo "我是儿子".PHP_EOL;
} else {
  echo "fork失败".PHP_EOL;
} 

Ergebnis:

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ php 123.php
我是父亲
我是儿子

Der zweite Abschnitt Code soll veranschaulichen, dass der untergeordnete Prozess eine Kopie der Daten des übergeordneten Prozesses hat, anstatt sie zu teilen:

// 初始化一个 number变量 数值为1
$number = 1;
$pid = pcntl_fork();
if ($pid > 0) {
    $number += 1;
    echo "我是父亲,number+1 : { $number }" . PHP_EOL;
} else if (0 == $pid) {
    $number += 2;
    echo "我是儿子,number+2 : { $number }" . PHP_EOL;
} else {
    echo "fork失败" . PHP_EOL;
}

Ergebnis

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ php 1234.php
我是父亲,number+1 : { 2 }
我是儿子,number+2 : { 3 }

Das obige ist der detaillierte Inhalt vonEine vorläufige Studie zu mehreren Prozessen in PHP7. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:cnblogs.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen