Ich habe dieses PECL-Paket namens threads gefunden , aber es gibt noch keine Version. Und auf der PHP-Website wird nichts angezeigt.
Ich habe dieses PECL-Paket namens threads gefunden , aber es gibt noch keine Version. Und auf der PHP-Website wird nichts angezeigt.
Antworten:
Es ist nichts verfügbar, von dem ich weiß. Das nächstbeste wäre, einfach ein Skript ein anderes über die CLI ausführen zu lassen, aber das ist ein bisschen rudimentär. Je nachdem, was Sie versuchen und wie komplex es ist, kann dies eine Option sein oder auch nicht.
Aus dem PHP-Handbuch für die Erweiterung pthreads :
pthreads ist eine objektorientierte API, die User-Land-Multithreading in PHP ermöglicht. Es enthält alle Tools, die Sie zum Erstellen von Multithread-Anwendungen für das Web oder die Konsole benötigen. PHP-Anwendungen können Threads, Worker und Stackables erstellen, lesen, schreiben, ausführen und synchronisieren.
So unglaublich das auch klingt, es ist völlig wahr. Heute kann PHP Multithreading für diejenigen, die es ausprobieren möchten.
In der ersten Version von PHP4, 22. Mai 2000, wurde PHP mit einer thread-sicheren Architektur ausgeliefert - eine Möglichkeit, mehrere Instanzen seines Interpreters in separaten Threads in SAPI-Umgebungen (Server API) mit mehreren Threads auszuführen. In den letzten 13 Jahren wurde das Design dieser Architektur beibehalten und weiterentwickelt: Seitdem wird sie auf den weltweit größten Websites in der Produktion eingesetzt.
Das Einfädeln in Benutzerland war für das PHP-Team nie ein Problem und ist es auch heute noch. Sie sollten verstehen, dass es in der Welt, in der PHP geschäftlich tätig ist, bereits eine definierte Skalierungsmethode gibt - Hardware hinzufügen. Im Laufe der vielen Jahre, in denen PHP existiert, ist Hardware immer billiger geworden, und so wurde dies für das PHP-Team immer weniger zu einem Problem. Während es billiger wurde, wurde es auch viel leistungsfähiger; Heutzutage verfügen unsere Mobiltelefone und Tablets über Dual- und Quad-Core-Architekturen und viel RAM. Unsere Desktops und Server verfügen normalerweise über 8 oder 16 Kerne, 16 und 32 Gigabyte RAM, obwohl wir möglicherweise nicht immer über zwei verfügen können Innerhalb des Budgets und mit zwei Desktops ist es für die meisten von uns selten nützlich.
Darüber hinaus wurde PHP für den Nicht-Programmierer geschrieben, es ist viele Hobbyisten Muttersprache. Der Grund, warum PHP so einfach zu übernehmen ist, ist, dass es eine leicht zu erlernende und zu schreibende Sprache ist. Der Grund, warum PHP heute so zuverlässig ist, liegt in der enormen Arbeit, die in das Design fließt, und in jeder einzelnen Entscheidung der PHP-Gruppe. Seine Zuverlässigkeit und Größe halten es nach all den Jahren im Rampenlicht; wo seine Rivalen auf Zeit oder Druck gefallen sind.
Multithread-Programmierung ist für die meisten nicht einfach, selbst mit der kohärentesten und zuverlässigsten API gibt es verschiedene Dinge zu bedenken und viele Missverständnisse. Die PHP-Gruppe möchte nicht, dass User Land Multithreading ein Kernmerkmal ist, es wurde nie ernsthaft darauf geachtet - und das zu Recht. PHP sollte nicht für alle komplex sein.
Alles in allem gibt es immer noch Vorteile, wenn PHP seine produktionsfertigen und getesteten Funktionen nutzen kann, um das Beste aus dem herauszuholen, was wir haben, wenn das Hinzufügen von mehr nicht immer eine Option ist und für viele von Aufgaben wird nie wirklich benötigt.
pthreads bietet für diejenigen, die es erkunden möchten, eine API, mit der ein Benutzer PHP-Anwendungen mit mehreren Threads ausführen kann. Die API ist in Arbeit und wird als Beta-Level für Stabilität und Vollständigkeit bezeichnet.
Es ist allgemein bekannt, dass einige der von PHP verwendeten Bibliotheken nicht threadsicher sind. Dem Programmierer sollte klar sein, dass pthreads dies nicht ändern können und nicht versuchen, es zu versuchen. Jede Bibliothek, die threadsicher ist, kann jedoch verwendet werden, wie bei jedem anderen threadsicheren Setup des Interpreters.
pthreads verwendet Posix-Threads (auch unter Windows). Der Programmierer erstellt echte Ausführungsthreads. Damit diese Threads jedoch nützlich sind, müssen sie sich mit PHP auskennen, um Benutzercode ausführen, Variablen gemeinsam nutzen und nützliche Kommunikationsmittel zulassen zu können (Synchronisation). Daher wird jeder Thread mit einer Instanz des Interpreters erstellt. Der Interpreter ist jedoch konstruktionsbedingt von allen anderen Instanzen des Interpreters isoliert - genau wie Server-API-Umgebungen mit mehreren Threads. pthreads versucht, die Lücke auf gesunde und sichere Weise zu schließen. Viele der Bedenken des Programmierers von Threads in C sind für den Programmierer von Pthreads einfach nicht vorhanden. Pthreads sind von Natur aus Kopie beim Lesen und Kopie beim Schreiben (RAM ist billig), sodass keine zwei Instanzen jemals dieselben physischen Daten manipulieren , aber beide können Daten in einem anderen Thread beeinflussen.
Warum beim Lesen kopieren und beim Schreiben kopieren:
public function run() {
...
(1) $this->data = $data;
...
(2) $this->other = someOperation($this->data);
...
}
(3) echo preg_match($pattern, $replace, $thread->data);
(1) Während eine Lese- und Schreibsperre für den Objektdatenspeicher von pthreads gehalten wird, werden Daten von ihrem ursprünglichen Speicherort in den Objektspeicher kopiert. pthreads passt den Refcount der Variablen nicht an. Zend kann die Originaldaten freigeben, wenn keine weiteren Verweise darauf vorhanden sind.
(2) Das Argument zu someOperation verweist auf den Objektspeicher, die gespeicherten Originaldaten, die selbst eine Kopie des Ergebnisses von (1) sind, werden für die Engine erneut in einen zval-Container kopiert, während dabei eine Lesesperre gehalten wird Im Objektspeicher wird die Sperre aufgehoben und die Engine kann die Funktion ausführen. Wenn das zval erstellt wird, hat es eine Refcount von 0, sodass die Engine die Kopie nach Abschluss des Vorgangs freigeben kann, da keine anderen Verweise darauf vorhanden sind.
(3) Das letzte Argument für preg_match verweist auf den Datenspeicher, eine Lesesperre wird erhalten, der Datensatz in (1) wird erneut mit einem Refcount von 0 in ein zval kopiert. Die Sperre wird aufgehoben. Der Aufruf von preg_match wird ausgeführt eine Kopie der Daten, dh selbst eine Kopie der Originaldaten.
Sachen zu wissen:
Die Hash-Tabelle des Objektspeichers, in der Daten threadsicher gespeichert werden,
basiert auf der von Zend mit PHP gelieferten TsHashTable.
Der Objektspeicher verfügt über eine Lese- und Schreibsperre. Für die TsHashTable wird eine zusätzliche Zugriffssperre bereitgestellt, sodass pthreads bei Bedarf (und zwar var_dump / print_r, direkter Zugriff auf Eigenschaften, auf die die PHP-Engine verweisen möchte) die TsHashTable manipulieren können außerhalb der definierten API.
Die Sperren werden nur gehalten, während die Kopiervorgänge ausgeführt werden. Wenn die Kopien erstellt wurden, werden die Sperren in einer sinnvollen Reihenfolge freigegeben.
Das heisst:
Wenn ein Schreibvorgang ausgeführt wird, wird nicht nur eine Lese- und Schreibsperre gehalten, sondern auch eine zusätzliche Zugriffssperre. Die Tabelle selbst ist gesperrt. Es gibt keine Möglichkeit, wie ein anderer Kontext sie sperren, lesen, schreiben oder beeinflussen kann.
Wenn ein Lesevorgang stattfindet, wird nicht nur die Lesesperre gehalten, sondern auch die zusätzliche Zugriffssperre, und die Tabelle wird erneut gesperrt.
Keine zwei Kontexte können physisch oder gleichzeitig auf dieselben Daten aus dem Objektspeicher zugreifen, aber Schreibvorgänge, die in einem beliebigen Kontext mit einer Referenz ausgeführt werden, wirken sich auf die Daten aus, die in einem beliebigen Kontext mit einer Referenz gelesen werden.
Dies wird nichts Architektur geteilt und der einzige Weg zu existieren ist das Nebeneinander. Diejenigen, die ein bisschen versiert sind, werden sehen, dass hier viel kopiert wird, und sie werden sich fragen, ob das eine gute Sache ist. Innerhalb einer dynamischen Laufzeit wird ziemlich viel kopiert, das ist die Dynamik einer dynamischen Sprache. pthreads wird auf Objektebene implementiert, da eine gute Kontrolle über ein Objekt erzielt werden kann, Methoden - der vom Programmierer ausgeführte Code - jedoch einen anderen Kontext haben, der frei von Sperren und Kopien ist - den lokalen Methodenbereich. Der Objektbereich im Fall eines pthreads-Objekts sollte als eine Möglichkeit behandelt werden, Daten zwischen Kontexten auszutauschen, das ist der Zweck. In diesem Sinne können Sie Techniken anwenden, um das Sperren des Objektspeichers zu vermeiden, sofern dies nicht erforderlich ist.
Die meisten für PHP verfügbaren Bibliotheken und Erweiterungen sind Thin Wrapper für Drittanbieter. Die PHP-Kernfunktionalität ist bis zu einem gewissen Grad dieselbe. pthreads ist kein dünner Wrapper um Posix Threads. Es ist eine Threading-API, die auf Posix-Threads basiert. Es macht keinen Sinn, Threads in PHP zu implementieren, die die Benutzer nicht verstehen oder nicht verwenden können. Es gibt keinen Grund, warum eine Person, die nicht weiß, was ein Mutex ist oder tut, nicht in der Lage sein sollte, alles zu nutzen, was sie hat, sowohl in Bezug auf Fähigkeiten als auch in Bezug auf Ressourcen. Ein Objekt funktioniert wie ein Objekt, aber wo immer zwei Kontexte kollidieren würden, bieten pthreads Stabilität und Sicherheit.
Jeder, der in Java gearbeitet hat, wird die Ähnlichkeiten zwischen einem pthreads-Objekt und dem Threading in Java erkennen. Dieselben Personen haben zweifellos einen Fehler namens ConcurrentModificationException gesehen - da es sich um einen Fehler handelt, der von der Java-Laufzeit ausgelöst wird, wenn zwei Threads dieselben physischen Daten schreiben gleichzeitig. Ich verstehe, warum es existiert, aber es verblüfft mich, dass mit so billigen Ressourcen wie ihnen die Laufzeit die Parallelität genau zu dem Zeitpunkt erkennen kann, zu dem die Sicherheit für den Benutzer erreicht werden kann, den er wählt Wirf zur Laufzeit einen möglicherweise schwerwiegenden Fehler aus, anstatt die Ausführung und den Zugriff auf die Daten zu verwalten.
Solche dummen Fehler werden von pthreads nicht ausgegeben. Die API wurde geschrieben, um das Threading so stabil und kompatibel wie möglich zu machen, glaube ich.
Multithreading ist nicht mit der Verwendung einer neuen Datenbank vergleichbar. Achten Sie besonders auf jedes Wort im Handbuch und auf Beispiele, die mit pthreads geliefert werden.
Zuletzt aus dem PHP-Handbuch:
pthreads war und ist ein Experiment mit ziemlich guten Ergebnissen. Alle Einschränkungen oder Funktionen können sich jederzeit ändern. das ist die Natur des Experimentierens. Die Einschränkungen, die häufig durch die Implementierung auferlegt werden, bestehen aus gutem Grund. Das Ziel von pthreads ist es, eine brauchbare Lösung für Multitasking in PHP auf jeder Ebene bereitzustellen. In der Umgebung, die pthreads ausführt, sind einige Einschränkungen und Einschränkungen erforderlich, um eine stabile Umgebung bereitzustellen.
Hier ist ein Beispiel dafür, was Wilco vorgeschlagen hat:
$cmd = 'nohup nice -n 10 /usr/bin/php -c /path/to/php.ini -f /path/to/php/file.php action=generate var1_id=23 var2_id=35 gen_id=535 > /path/to/log/file.log & echo $!';
$pid = shell_exec($cmd);
Grundsätzlich führt dies das PHP-Skript in der Befehlszeile aus, gibt jedoch sofort die PID zurück und wird dann im Hintergrund ausgeführt. (Das echo $! Stellt sicher, dass nichts anderes als die PID zurückgegeben wird.) Auf diese Weise kann Ihr PHP-Skript fortgesetzt oder beendet werden, wenn Sie möchten. Wenn ich dies verwendet habe, habe ich den Benutzer auf eine andere Seite umgeleitet, auf der alle 5 bis 60 Sekunden ein AJAX-Aufruf durchgeführt wird, um zu überprüfen, ob der Bericht noch ausgeführt wird. (Ich habe eine Tabelle zum Speichern der gen_id und des Benutzers, auf den sie sich bezieht.) Das Überprüfungsskript führt Folgendes aus:
exec('ps ' . $pid , $processState);
if (count($processState) < 2) {
// less than 2 rows in the ps, therefore report is complete
}
Es gibt hier einen kurzen Beitrag zu dieser Technik: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/
Kurz gesagt: Ja, es gibt Multithreading in PHP, aber Sie sollten stattdessen Multiprocessing verwenden.
Es gibt immer ein bisschen Verwirrung über die Unterscheidung von Threads und Prozessen, daher werde ich beide kurz beschreiben:
Sie können paralleles Rechnen erreichen, indem Sie mit PHP neue Prozesse erstellen (die auch einen neuen Thread enthalten). Wenn Ihre Threads nicht viel Kommunikation oder Synchronisation benötigen, haben Sie die Wahl, da die Prozesse isoliert sind und die Arbeit des anderen nicht beeinträchtigen können. Selbst wenn einer abstürzt, geht das die anderen nicht an. Wenn Sie viel Kommunikation benötigen, sollten Sie unter "Multithreading" weiterlesen oder - leider - eine andere Programmiersprache verwenden, da die Kommunikation und Synchronisation zwischen Prozessen viel Teint mit sich bringt.
In PHP gibt es zwei Möglichkeiten, einen neuen Prozess zu erstellen:
Lassen Sie das Betriebssystem dies für Sie tun : Sie können Ihr Betriebssystem anweisen, einen neuen Prozess zu erstellen und ein neues (oder dasselbe) PHP-Skript darin auszuführen.
Für Linux können Sie Folgendes verwenden oder die Antwort von Darryl Hein in Betracht ziehen :
$cmd = 'nice php script.php 2>&1 & echo $!';
pclose(popen($cmd, 'r'));
Für Windows können Sie Folgendes verwenden:
$cmd = 'start "processname" /MIN /belownormal cmd /c "script.php 2>&1"';
pclose(popen($cmd, 'r'));
Mach es selbst mit einer Gabel : PHP bietet auch die Möglichkeit, die Gabelung über die Funktion pcntl_fork () zu verwenden . Ein gutes Tutorial dazu finden Sie hier, aber ich empfehle dringend, es nicht zu verwenden, da Gabel ein Verbrechen gegen die Menschlichkeit und insbesondere gegen oop ist.
Beim Multithreading teilen alle Ihre Threads ihre Ressourcen, sodass Sie ohne großen Aufwand problemlos zwischen ihnen kommunizieren und sie synchronisieren können. Auf der anderen Seite muss man wissen, was man tut, da Rennbedingungen und Deadlocks einfach zu produzieren, aber sehr schwer zu debuggen sind.
Standard-PHP bietet kein Multithreading, aber es gibt eine (experimentelle) Erweiterung, die dies tatsächlich tut - Pthreads . Seine API-Dokumentation hat es sogar in php.net geschafft . Damit können Sie einige Dinge wie in echten Programmiersprachen tun :-) wie folgt:
class MyThread extends Thread {
public function run(){
//do something time consuming
}
}
$t = new MyThread();
if($t->start()){
while($t->isRunning()){
echo ".";
usleep(100);
}
$t->join();
}
Für Linux gibt es hier bei stackoverflow's eine Installationsanleitung .
Für Windows gibt es jetzt eines:
Bearbeiten Sie [phpDirectory] /php.ini und fügen Sie die folgende Zeile ein
extension=php_pthreads.dll
Testen Sie es mit dem obigen Skript mit etwas Schlaf oder etwas genau dort, wo der Kommentar ist.
Und jetzt das große ABER : Obwohl dies wirklich funktioniert, war PHP ursprünglich nicht für Multithreading gemacht. Es gibt eine thread-sichere Version von PHP und ab Version 5.4 scheint es nahezu fehlerfrei zu sein, aber die Verwendung von PHP in einer Multithread-Umgebung wird im PHP-Handbuch immer noch nicht empfohlen (aber möglicherweise haben sie ihr Handbuch einfach nicht aktualisiert dies noch). Ein viel größeres Problem könnte sein, dass viele gängige Erweiterungen nicht threadsicher sind . Möglicherweise erhalten Sie Threads mit dieser PHP-Erweiterung, aber die Funktionen, von denen Sie abhängig sind, sind immer noch nicht threadsicher, sodass Sie wahrscheinlich auf Rennbedingungen, Deadlocks usw. in Code stoßen, den Sie nicht selbst geschrieben haben ...
Sie können pcntl_fork () verwenden , um etwas Ähnliches wie Threads zu erreichen. Technisch gesehen handelt es sich um separate Prozesse, sodass die Kommunikation zwischen beiden mit Threads nicht so einfach ist, und ich glaube, dass es nicht funktionieren wird, wenn PHP von Apache aufgerufen wird.
Wenn es jemanden interessiert, habe ich php_threading wiederbelebt (nicht dasselbe wie Threads, aber ähnlich) und ich habe es tatsächlich bis zu dem Punkt, an dem es (etwas) gut funktioniert!
pcntl_fork()
ist das, wonach Sie suchen, aber sein Prozess gibt kein Threading. Sie haben also das Problem des Datenaustauschs. Um sie zu lösen, können Sie PHPS-Semaphorfunktionen ( http://www.php.net/manual/de/ref.sem.php ) verwenden. Nachrichtenwarteschlangen sind am Anfang möglicherweise etwas einfacher als Segmente mit gemeinsamem Speicher.
Wie auch immer, eine Strategie, die ich in einem von mir entwickelten Webframework verwende, das ressourcenintensive Blöcke einer Webseite (wahrscheinlich mit externen Anforderungen) parallel lädt: Ich mache eine Jobwarteschlange, um zu wissen, auf welche Daten ich warte, und dann verzweige ich mich aus den Jobs für jeden Prozess. Sobald dies erledigt ist, speichern sie ihre Daten im APC-Cache unter einem eindeutigen Schlüssel, auf den der übergeordnete Prozess zugreifen kann. Sobald alle Daten vorhanden sind, werden sie fortgesetzt. Ich benutze einfach usleep()
zu warten, weil prozessübergreifende Kommunikation in Apache nicht möglich ist (Kinder verlieren die Verbindung zu ihren Eltern und werden Zombies ...). Das bringt mich zum letzten Punkt: Es ist wichtig, jedes Kind selbst zu töten! Es gibt auch Klassen, die Prozesse verzweigen, aber Daten behalten. Ich habe sie nicht untersucht, aber das Zend-Framework hat eine, und sie codieren normalerweise langsam, aber zuverlässig. Sie finden es hier:
http://zendframework.com/manual/1.9/en/zendx.console.process.unix.overview.html
Ich denke, sie verwenden shm-Segmente! Nun, last but not least gibt es einen Fehler auf dieser Zend-Website, ein kleiner Fehler im Beispiel.
while ($process1->isRunning() && $process2->isRunning()) {
sleep(1);
}
should of course be:
while ($process1->isRunning() || $process2->isRunning()) {
sleep(1);
}
Es gibt eine Threading Erweiterung activley auf PThreads basierend entwickelt , dass sieht sehr vielversprechend an https://github.com/krakjoe/pthreads
Nur ein Update, es scheint, dass PHP-Leute daran arbeiten, Thread zu unterstützen und es ist jetzt verfügbar.
Hier ist der Link dazu: http://php.net/manual/en/book.pthreads.php
Ich habe eine PHP-Threading-Klasse, die seit über zwei Jahren in einer Produktionsumgebung einwandfrei läuft.
BEARBEITEN: Dies ist jetzt als Komponistenbibliothek und als Teil meines MVC-Frameworks Hazaar MVC verfügbar.
Ich weiß, dass dies eine sehr alte Frage ist, aber Sie können sich http://phpthreadlib.sourceforge.net/ ansehen.
Bidirektionale Kommunikation, Unterstützung für Win32 und keine Erweiterungen erforderlich.
Schon mal was davon gehört appserver
von techdivision gehört?
Es ist in PHP geschrieben und arbeitet als App-Server, der Multithreads für PHP-Anwendungen mit hohem Datenverkehr verwaltet. Ist noch in der Beta aber sehr vielversprechend.
Es gibt die eher obskure und bald veraltete Funktion namens Zecken . Das einzige, wofür ich es jemals verwendet habe, ist, einem Skript zu erlauben, SIGKILL (Strg + C) zu erfassen und ordnungsgemäß zu schließen.
pcntl_fork()
) funktioniert, wenn es von Apache aufgerufen wird?