Heim > Backend-Entwicklung > PHP-Tutorial > PHPs Unterstützung und Verwendung von Multithread-Programmierung

PHPs Unterstützung und Verwendung von Multithread-Programmierung

*文
Freigeben: 2023-03-18 09:20:01
Original
2208 Leute haben es durchsucht

Im Bereich PHP ist das Konzept des Multithreadings nicht so bekannt wie in anderen Sprachen. Ich dachte, dass PHP im Allgemeinen ein Single-Thread-Modell ist und nicht für Multi-Thread-Felder geeignet ist. Nachdem ich den Quellcode einiger Multithread-Projekte durchgesehen hatte, stellte ich fest, dass das Multithreading von PHP auch großartige Einsatzmöglichkeiten bietet. Bei flexiblem Einsatz erweist es sich als sehr geeignet zur Lösung bestimmter Probleme.

Multi-Threading

Threads

Lassen Sie uns zunächst über Threads sprechen:

Thread ist die kleinste Einheit, die das Betriebssystem Vorgänge planen kann. Es wird in den Prozess eingebunden und ist die eigentliche Bedieneinheit im Prozess. Ein Thread bezieht sich auf einen einzelnen sequenziellen Kontrollfluss in einem Prozess, und jeder Thread führt unterschiedliche Aufgaben parallel aus.

Die Verwendung von Multithreading hat vor allem Vorteile bei der Ausführungseffizienz Ein großer Vorteil. Da ein Thread die kleinste Einheit ist, die das Betriebssystem planen kann:

Ein Multithread-Programm hat eine größere Wahrscheinlichkeit, vom Betriebssystem geplant zu werden als ein Single-Threaded-Programm, also sind Multithread-Programme im Allgemeinen dies effizienter als Single-Thread-Programme;

Mehrere Threads eines Multi-Thread-Programms können gleichzeitig auf mehreren Kernen einer Multi-Core-CPU ausgeführt werden, wodurch die Vorteile der Multi-Core-Maschine voll ausgenutzt werden können.

Im Vergleich zu Multiprozessprogrammen gleichzeitig weist Multithreading die folgenden Merkmale auf:

Der Systemaufwand beim Erstellen und Wechseln von Threads ist geringer als bei Prozessen und daher höher Bis zu einem gewissen Grad effizienter als mehrere Prozesse; Threads teilen sich von Natur aus den Speicherplatz und die Kommunikation zwischen Threads ist einfacher. Vermeidet die Einführung neuer Komplexität durch Prozess-IPC.

Anwendbare Szenarien

Es gibt viele Optimierungen für Multithreading, aber die sinnlose Verwendung von Multithreading kann die Ausführungseffizienz des Programms nicht verbessern, da die Erstellung und Zerstörung von Threads, der Kontextwechsel usw. Thread-Synchronisation usw. haben ebenfalls einen Leistungsverlust, der länger dauern kann als die sequentielle Ausführung von Code. Beispiel:

sumSmall ist eine Funktion, die von 1 bis 50000 akkumuliert.

PHPs Unterstützung und Verwendung von Multithread-ProgrammierungDas obige Bild ist ein Vergleich der Zeit, in der sumSmall dreimal im Hauptthread und sumSmall jeweils in drei Threads ausgeführt wird und dann die Ergebnisse synchronisiert werden Wir werden feststellen, dass nur die Ausführungszeit des Hauptthreads tatsächlich kürzer ist. Die Zeit zum Erstellen, Wechseln und Synchronisieren der drei Threads ist weitaus größer als die Zeit, die durch die asynchrone Ausführung der Threads eingespart wird.

Die Funktion sumLarge akkumuliert von 1 bis 5000000. Die folgende Abbildung zeigt die Zeit, die benötigt wird, um denselben Thread dreimal und drei Threads auszuführen:

PHPs Unterstützung und Verwendung von Multithread-ProgrammierungDieses Mal , Multithreading Schließlich gibt es einen Effizienzvorteil.

Ob Multithreading verwendet werden soll, muss entsprechend den spezifischen Anforderungen bestimmt werden. Im Allgemeinen werden die folgenden zwei Situationen berücksichtigt:

E/A-Blockierung führt zu einer Aufgabenplanung im Betriebssystem und Blockierung die aktuelle Aufgabe, also im Code Wenn viele E/A vorhanden sind, kann der Code bei Verwendung von Multithreading parallelisiert werden. Beispielsweise das mehrfache Lesen einer gesamten Datei oder das Anfordern mehrerer Netzwerkressourcen.

Multithreading kann die CPU voll ausnutzen. Wenn also mehrere rechenintensive Codes vorhanden sind, können Sie sie auch mit Multithreading parallel ausführen, wie im letzten Beispiel oben.

Multi-Threading in PHP

PHP unterstützt standardmäßig kein Multi-Threading. Um Multi-Threading zu verwenden, müssen Sie die pthread-Erweiterung installieren Der Parameter --enable-maintainer-zts gibt die Verwendung der Thread-Sicherheit beim Kompilieren von PHP an.

Thread-Sicherheit

Multi-Threading ist ein Faktor, der Programme unruhig macht. Bevor Sie Multi-Threading verwenden, müssen Sie zunächst Thread-Sicherheit berücksichtigen:

Thread-Sicherheit: Thread-Sicherheit ist ein Begriff aus der Programmierung, der bedeutet, dass eine bestimmte Funktion oder Funktionsbibliothek beim Aufrufen in einer Multithread-Umgebung gemeinsam genutzte Variablen zwischen mehreren Threads korrekt verarbeiten kann, sodass die Programmfunktion korrekt ausgeführt werden kann.

Da beim herkömmlichen Multithreading mehrere Threads Variablen gemeinsam nutzen, können die folgenden Probleme auftreten:

Es gibt ein globales Array $arr = array('a');;

Ein Thread erhält die Array-Länge 1;

B-Thread erhält die Array-Länge 1;

Ein Thread entfernt das Array-Element $a = array_pop($arr); = 'a';;

Thread B öffnet auch Array-Elemente $b = array_pop($arr); $a = null;;

Zu diesem Zeitpunkt ereignete sich ein übernatürliches Ereignis in Thread B , Offensichtlich Die Array-Länge ist größer als 0, sonst springt nichts heraus;

PHP-Implementierung

Die von PHP implementierte Thread-Sicherheit verwendet hauptsächlich den TSRM-Mechanismus, um globale Variablen und statische Variablen zu isolieren und zu trennen Globale Variablen und statische Variablen werden in jeden Thread kopiert, und jeder Thread verwendet eine Sicherung des Hauptthreads, wodurch Variablenkonflikte und Thread-Sicherheitsprobleme vermieden werden.

Die Multi-Thread-Kapselung von PHP gewährleistet die Thread-Sicherheit. Programmierer müssen nicht mehr über das Hinzufügen verschiedener Sperren zu globalen Variablen nachdenken, um Lese- und Schreibkonflikte zu vermeiden. Außerdem wird die Wahrscheinlichkeit von Fehlern verringert und der geschriebene Code sicherer.

Aber das Ergebnis ist, dass, sobald der Sub-Thread mit der Ausführung beginnt, der Haupt-Thread die Ausführungsdetails des Sub-Threads nicht mehr anpassen kann und der Thread die Fähigkeit verliert, Nachrichten zwischen Threads über globale Variablen weiterzuleiten ein gewisses Maß.

Gleichzeitig kommt es nach dem Aktivieren der Thread-Sicherheitsoption zu zusätzlichen Verlusten, wenn der TSRM-Mechanismus zum Zuweisen und Verwenden von Variablen verwendet wird. Daher kommt es in einer PHP-Umgebung, die kein Multithreading erfordert, zu zusätzlichen Verlusten. Verwenden Sie die ZTS-Version (Nicht-Thread-Sicherheit) von PHP.

Klassen und Methoden

PHP kapselt Threads in die Thread-Klasse. Aufgrund der Kapselung der Klasse kann die Verwendung von Variablen nur über den Konstruktor übergeben werden, und die Thread-Operation erfolgt müssen auch ausgehend von Klassenvariablen übergeben werden.

Im Folgenden werden einige häufig verwendete Thread-Klassenmethoden vorgestellt:

run():此方法是一个抽象方法,每个线程都要实现此方法,线程开始运行后,此方法中的代码会自动执行;
start():在主线程内调用此方法以开始运行一个线程;
join():各个线程相对于主线程都是异步执行,调用此方法会等待线程执行结束;
kill():强制线程结束;
isRunning():返回线程的运行状态,线程正在执行run()方法的代码时会返回 true;
Nach dem Login kopieren

Aufgrund der Implementierung der Thread-Sicherheit können PHP-Multithreads nach dem Start ihrer Ausführung nicht mehr über den gemeinsam genutzten Speicher kommunizieren Speicherplatz und Threads können nicht durch Kommunikation zwischen Threads wiederverwendet werden, daher denke ich, dass der „Thread-Pool“ von PHP keinen Sinn ergibt. Die mit der Erweiterung gelieferte Pool-Klasse ist eine Klasse, die die Multi-Thread-Zuweisung verwaltet und hier nicht vorgestellt wird.

Beispielcode

Das Folgende ist eine Thread-Klasse, die zum Anfordern einer bestimmten Schnittstelle verwendet wird. Schreiben Sie als Nächstes zwei darauf basierende Multithread-Anwendungsbeispiele:

class Request extends Thread {
    public $url;
    public $response;
    public function __construct($url) {
        $this->url = $url;
    }
    public function run() {
        $this->response = file_get_contents($this->url);
    }
}
Nach dem Login kopieren

Asynchrone Anfrage

Teilen Sie die synchrone Anfrage in mehrere Threads für asynchrone Aufrufe auf, um die Laufeffizienz des Programms zu verbessern.

$chG = new Request("www.google.com");
$chB = new Request("www.baidu.com");
$chG ->start();
$chB ->start();
$chG->join();
$chB->join();
$gl = $chG->response;
$bd = $chB->response;
Nach dem Login kopieren

Timeout-Kontrolle

Ich habe zufällig entdeckt, dass ein Inhalt auf einer bestimmten Seite der Website des Unternehmens kommt und geht. Ich kenne die konkrete Implementierung nicht, aber das hat mir geholfen Die Inspiration für die Verwendung von Multithreading: Die asynchrone Verwendung von Thread implementiert eine schnelle Fehler- und Timeout-Kontrolle.

Wenn wir Curl verwenden, um eine Adresse anzufordern, können wir das Verbindungs-Timeout und das Lesedaten-Timeout von Curl über die Parameter CURLOPT_CONNECTTIMEOUT / CURLOPT_TIMEOUT festlegen, aber das Gesamt-Timeout ist schwer zu steuern. Darüber hinaus kann der Timeout-Zeitraum bei der Durchführung von Datenbankabfragen nicht festgelegt werden (Blog von Niao Ge: Setting query timeout for MySQL).

Zu diesem Zeitpunkt können wir Multithreading verwenden, um diese Funktion zu implementieren: Rufen Sie nach dem Ausführen der start()-Methode der Thread-Klasse nicht die join()-Methode auf, damit der Thread asynchron bleibt Zustand und blockiert nicht die Ausführung des Hauptthreads.

Zu diesem Zeitpunkt entspricht der Hauptthread dem Flaggschiff und jeder Unterthread entspricht dem Kreuzer. Nachdem das Flaggschiff an einem bestimmten Ort angekommen ist, muss nicht auf die Rückkehr des Kreuzers gewartet werden . Es kann einfach eine Zeit lang warten und losfahren, wodurch Unfälle des Kreuzers vermieden werden, wenn das Flaggschiff umsonst ist.

Code:

$chG = new Request("www.google.com");
$chB = new Request("www.baidu.com");
$chG->start();
$chB->start();
$chB->join();
// 此处不对chG执行join方法
sleep(1); // sleep一个能接受的超时时间
$gl = $chG->response;
$bd = $chB->response;
$bd->kill();
if (!$gl) {
    $gl = ""; // 处理异常,或在线程类内给$gl一个默认值
}
Nach dem Login kopieren

Zusammenfassung

PHPs versiegelte (yan) Installation (ge) von Multithreading macht Menschen bei der Verwendung von Threads sehr unzufrieden. Obwohl es sicher ist und den einfachen und benutzerfreundlichen Stil von PHP beibehält, kann es die Multithreading-Funktionen nicht vollständig nutzen. Allerdings hat jede Sprache ihre eigenen Merkmale und Schwerpunkte, daher besteht kein Grund, sie zu erzwingen. Wenn Sie sie lieben, müssen Sie sie tolerieren =_=.

Verwandte Empfehlungen:

Beispiel zur asynchronen Multithread-Swoole-Nutzung von PHP

Ein Fall der Implementierung der PHP-Multithreading-Klasse

PHP-Multithreading-Kleinfall

Das obige ist der detaillierte Inhalt vonPHPs Unterstützung und Verwendung von Multithread-Programmierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage