Arbeitet ein Server Anfragen hintereinander ab oder auch gleichzeitig?

...komplette Frage anzeigen

5 Antworten

Die bisherigen Antworten sind leider falsch.

Natürlich werden Serveranfragen parallel verarbeitet, und das sogar bei nur einer einzigen CPU mit nur einem einzigen Kern!

Wenn es anders wäre, könnte man das Internet mit seinen Webservern in der heutigen Form kaum benutzen und Seitenanfragen würden ewig laden, mit einer Latenz wesentlich höher als zu Modem-Zeiten!

Deshalb kannst du in PHP auch keine Datei auslesen, den Wert um eins erhöhen und das Ganze dann wieder in die Datei schreiben! Dabei WIRD es früher oder später zu einer sog. Race-Condition kommen.

Die Parallelisierung von solchen Aufgaben ist eine Wissenschaft für sich, und da PHP so eine primitive Skriptsprache ist, gibt es leider auch keine andere Möglichkeit die einzelnen Prozesse / Threads zu synchronisieren, ohne eine Datei zu öffnen und mit der flock()-Funktion zu sperren.

In deinem Falle, ist "einen Integer in einer Textdatei um eins erhöhen" wegen dieser mangelnden Sprachfeatures leider mindestens eine 50-Zeilen lange Funktion. Eine kürzere Lösung gibt es nicht, ohne dass die hohe Wahrscheinlichkeit besteht, dass sich mehrere Requests in die Haare kriegen.

Leider wirst du zu diesem Thema - wie die anderen drei Antworten - oft falsche HInweise bekommen, da PHP-Programmierer überdurchschnittlich oft die Parallelisierung von Resourcen (Dateien, Datenbanken, etc.) vernachlässigen.

Fazit: Wenn du bei deinem Zähler die einzelnen Zugriffe nicht mittels flock() ordentlich sperrst, WIRST du einige Zugriffe fälschlicherweise mit alten Werten inkrementieren, und dein Counter wird somit einige "Hits" übersehen, was zu ungenauen Ergebnissen führt.

Leider verursachen die meisten Counterskripte (die sogar MySQL oder SQLite benutzen) solche Fehler.

Bei vielen gleichzeitigen Zugriffen (ca. einige zich pro Sekunde) funktioniert das dann nicht mehr zuverlässig!

Also es gibt zwei Möglichkeiten:

  • Du sperrst den kritischen Bereich aus "lesen", "erhöhen" und "schreiben" mit einem File-Lock.

  • Dir sind ungenaue und fehlerhafte Ergebnisse recht, und du machst es ohne Lock.

Viel Spaß noch beim programmieren! :)

PS: Da PHP dafür leider völlig ungeeignet ist, guck dir mal eine weitere "richtige" Programmier- oder Skriptsprache an, die ebenfalls mit Prozessen und Threads arbeitet und solche sachen wie wait(), notify(), Semaphoren, Mutexe, Locks, RLocks, usw. bereitstellt. Und sei es nur, um ein Gefühl für Paralellisierung zu bekommen! Was PHP Programmierer teilweise mit Resourcen-IO anrichten ist wirklich ein graus! (Guck dir mal Python, C#, Java oder C/C++ mit Zusatzbibliotheken wie pthreads, usw. an, falls du nicht weißt, wo du anfangen sollst!)

Viel Erfolg! :)

PS: Mir ist gerade noch aufgefallen, dass dein Counter im schlimmsten Falle sogar auf 0 bzw. 1 zurückgesetzt werden kann, wenn der Scheduler bei Request A direkt nach fread() und ftruncate() zu Request B wechselt.

Nehmen wir mal an, bei Request A hat jetzt den String "1000" gelesen und kurz vor dem fwrite() von "1001" wird dann zu Request B gewechselt.

Request B würde dann einen leeren String erhalten, welchen die intval() Funktion in einen echten Integer mit dem Wert "0" konvertiert. (Da Request A ja eben bereits ftruncate() in Vorbereitung zu fwrite() aufgerufen hat, und die Datei jetzt kurzzeitig die Länge Null hat.)

Jetzt wird wieder gewechselt, und Request A schreibt "1001" in die Datei. Request A ist jetzt mit seiner Arbeit fertig, und der Scheduler wechselt wieder zu Request B.

Dort wird der Wert (den wir fälschlicherweise als "0" erhalten haben) inkrementiert somit zu "1". Diese "1" wird als Ergebnis zurück in die Datei geschrieben.

Und bammmm ... dein Counter wurde von 1001 auf 1 zurück gesetzt, wegen besagter Race-Condition.

Der Zählvorgang würde dann so aussehen:

....
998
999
1000
[Race-Condition]
1
2
...

Im harmlosesten Falle wird - wie ich eingangs in meiner Antwort geschrieben habe, "nur" ein Wert "übersehen", was dann so aussehen könnte:

...
998
999
1000
[Race-Condition]
1000
1001
...

Wie du siehst, wird zwei (!) mal die "1000" gezählt, obwohl nach der ersten "1000" bereits "1001" folgen sollte.

Und wir reden hier nur von Request A und B ... jetzt stell dir mal vor, was passiert, wenn du hunderte oder tausende gleichzeitige Anfragen hast. Dabei steigt die Wahrscheinlichkeit für Race-Conditions dann exponentiell an.

Wie gesagt, fast alle Counter, die ich bis jetzt gesehen haben, sogar die, die Datenbanken anstatt Dateien benutzen, haben solche Race-Conditions! In PHP fehlt einfach ein effizientes Mittel, um Code-Bereiche zu synchronisieren. (So etwas wie eine abgewandelte "synchronized" Anweisung wie in Java, allerdings mit einem Mixed-Value als Monitor wäre genial.)

Die momentan einzige Möglichkeit mit flock() ist extrem Resourcenhungrig und ein absolutes Knickei, welches bei hochfrequentierten Servern die Performance drastisch senkt!

0

Hallo

ch will in eine Textdatei eine Zahl auslesen und diese dann +1 rechnen.

in eine Datei auslesen, was ist das denn?

Soll da ein Wert der in einer Textdatei steht geändert werden oder wohin soll die Berechnung gehen?

dies soll aber für jeden einzelnen aufruf der Seite enstehen.

Wenn die Datei gerade bearbeitet wird und ein anderer diese ebenfalls öffnet, dann ist diese für den Anderen nicht beschreibbar, bzw. wird im Cache gehalten. Am Ende steht das drinnen was der letzte darin gespeichert hat.

Und kann es da sein das der Server gleichzeitig auf die Datei zugreift und irgendwas falsches rein schreibt oder arbeitet der jeden Nutzer einzeln ab bis das Script durchgelaufen ist?

Das auslesen der Datei geschieht schon gleichzeitig, der Schreibvorgang aber in Reihenfolge - Ist doch logisch, wäre ja blöd wenn die Seite nur für einen Betrachter da wäre.

Wie wäre es denn wenn Du mal darlegst was das Ziel ist, eventuell gibt es ja einen Weg den Du noch nicht in Betracht gezogen hast.

Linuxhase

Nein, die Anfragen werden einzeln nacheinander bearbeitet. Zumindest soweit ich mich erinnern kann, meine PHP-Zeiten liegen schon etwas zurück. :)

Nein, das ist falsch. Siehe meine Antwort! :)

0

Immer hintereinander. Alles was an Computern/Servern parallel abläuft ist nur pseudoparallel, da die auszuführenden Tätigkeiten dann in Threads oder Prozessen ablaufen. Demnach zwingend nacheinander.

Natürlich laufen Prozesse parallel ab! Welche Server sind denn heute keine Mehrkern- bzw. Mehrprozessorsysteme mehr?

Deshalb wird ein großer Teil der Anfragen auch auf verschiedenen Kernen oder Prozessoren ausgeführt, und zwar echt (!) parallel! :)

1

Ihr habt beide recht ;)

0

Die Päckchen werden eigendlich nach einander bearbeitet, soweit ich weis.

Das trifft für die einzelnen Pakete sehr low level in der Netzwerkkarte zu, aber direkt danach werden die auf Prozesse und Threads verteilt, weshalb PHP auch mehrere Antworten gleichzeitig abarbeitet. Zumindest in unbestimmbaren kleinen Häppchen auf Singlecoresystemen, was aber keinen Unterschied für die Parallelisierbarkeit macht.

0

Was möchtest Du wissen?