phpbar.de logo

Mailinglisten-Archive

[php] Schlafende Prozesse / flock() / ignore_user_abort() / file_get_contents()

[php] Schlafende Prozesse / flock() / ignore_user_abort() / file_get_contents()

Thomas Koudela thomas at koudela.net
Di Mär 16 13:09:19 CET 2010


Hi.

> Wenn sich viele Benutzer gleichzeitig auf meiner Seite tummeln, gehen
> manche Funktionen in die Knie, z. B. die Suchfunktion. Das liegt meiner
> Vermutung nach jedoch nicht an der Suche selbst,

Wenn es nicht an diesen Funktionen selbst liegt, warum tritt es Deiner
Meinung dann nur bei _manchen_ Funktionen auf?

> sondern daran, dass
> der Server eine Vielzahl von "schlafenden" Prozessen ansammelt, und
> diese "Karteileichen" den "echten" Prozessen Rechenzeit oder Zugriffs-
> rechte abtrünnig machen. (Auch wenn es nicht direkt etwas mit PHP zu
> tun hat: Wie kommt es eigentlich zu diesen "schlafenden" Prozessen?
> Was machen die? Wachen die irgendwann mal wieder auf oder werden sie
> doch noch beendet?)

Ein schlafender Prozess ist ein Programm, welches auf seinen Einsatz
wartet. Damit es in dieser Zeit keine Rechenleistung verschleudert
schläft es im Arbeitsspeicher. Ein schlafender Prozess dürfte IMHO keine
Zugriffsrechte blockieren - es sei denn die Programmierer haben Mist
gebaut.

> Ein Problem könnte darin liegen, dass die Suche manche Bereiche der
> Seite "indiziert", d. h. eine Art Zusammenfassung erstellt und diese
> speichert. (Wenn sich bis zur nächsten Suche nichts ändert, kann die
> Zusammenfassung wiederverwendet werden und spart dann Zeit.) Bei den
> Dateioperationen benutze ich die flock()-Funktion in ihrer Reinform,
> auch wenn mir bewusst ist, dass ein fopen(..., 'w') nicht wirklich dazu
> passt. Um das Thema "Abbruch durch den Benutzer" habe ich mich bisher
> noch nicht gekümmert. Kann es also sein, dass ein Abbruch nach flock()
> die folgenden Prozesse ausbremst, die sich mit flock() auf die gleiche
> Datei beziehen? Kann ich das mit ignore_user_abort() in geordnete
> Bahnen lenken?

Natürlich ist ein Script-Abbruch bei gesperrten Datei ziemlich fatal,
wenn keine Vorkehrungen zur Entsperrung im Fehlerfall getroffen wurden.
Sinnvoll wäre, wenn PHP beim Schließen der Datei oder spätestens nach
Ende des Scriptes alle noch gesperrten Dateien automatisch entsperrt.
Ich weiß allerdings nicht, ob die PHP-Entwickler so etwas implementiert
haben. Ich würde eine Datenbanklösung vorziehen, zumal Du dann mehrere
Indizierungen speichern könntest und absolut sicher wärst, dass die
Implementierung auf jedem System gleich gehandhabt wird. Wenn Du die
Datenbank intelligent nutzt, müsstest Du in Deinem Fall auch auf den
Lock verzichten können.

> Dann zu flock(): http://www.php.net/manual/de/function.flock.php
> bietet in den Benutzerkommentaren viele Anregungen, wie man aus dem
> etwas ungeschickten Ansatz, den Zugriff erst nach Öffnen zu sperren,
> etwas Brauchbares macht. Ist
> 
>    $fp = fopen(..., 'a'); // <- Dateiinhalt erst bewahren
>    flock($fp, LOCK_EX);
>    ftruncate($fp, 0);     // <- jetzt erst löschen
>    fputs($fp, ...);
>    flock($fp, LOCK_UN);
>    fclose($fp);
> 
> der "richtige" Ansatz als Ersatz für fopen(..., 'w') + flock()? Sehe
> ich das richtig, dass auch fopen(..., 'r') mit flock() kombiniert
> werden muss, damit das Konzept stimmig ist? Und was ist mit Funktionen
> wie file_get_contents() / file_put_contents()?

Bei file_get_contents() und file_put_contents() ist die dargestellte
Kombination mit flock() überflüssig, da in einem Rutsch gelesen bzw.
geschrieben wird. Eigentlich bezweifle ich, dass das dargestellte
überhaupt Sinn macht, denn sobald eine Datei zum Schreiben geöffnet
wird, müsste automatisch auf Betriebssystemebene, die Datei für andere
Prozesse gesperrt sein, bzw. warten bis nicht mehr aus der Datei gelesen
wird. Sonst könnte es zu Konflikten zwischen unabhängigen Programmen
kommen! Konflikte kann ich mir nur bei Multi-Thread-Servern vorstellen,
welche den Zugriff auf eine externe Ressource intern vorverwalten. 

> Für Hilfestellung jeder Art bin ich dankbar; auch Hinweise / Vermutun-
> gen, dass das Problem vielleicht ganz woanders liegt. Ach ja: Wenn der
> Server ganz zu hängen scheint, hilft es manchmal, das Session-Cookie
> im Browser zu löschen und die Seite neu zu laden, dann geht's. (Weiß
> zwar nicht, ob das irgendetwas mit dem Problem zu tun hat, aber ich
> erwähne es lieber mal.)

Unter den Beiträgen zur Funktion flock() gibt es jemanden, der darauf
hinweist, dass er bei 20 Anfragen in der Sekunde auf einen exklusiven
Lock der Apache-Server 100% der CPU-Leistung auffraß ohne abzubrechen.
Er gibt zwar einen Workaround an, aber spätestens da, wäre die
Entscheidung für eine Datenbanklösung bei mir gefallen.


beste Grüße,
Thomas



php::bar PHP Wiki   -   Listenarchive