Tom: memcached - ist mein erstelltes locking falsch?

Beitrag lesen

Hello,

---->solange (kein_eigenes_Signal_erstellt_werden_kann) --+
      ^                                                       |
      +-------------------------------------------------------+

anschließend_verändere_die_Variable;

nimm_das_Signal_wieder_weg;

ACHSOO!
DU willst ihn also in einer Schleife warten lassen. Und erst dann im Skript weitergehen.

Den Besucher?
Das oben beschriebene ist ein "Blocking Lock".
Begriffsbestimmung z.B.: http://msdn.microsoft.com/en-us/library/aa266504(VS.60).aspx

Es gibt in Memcache ein Array. Während einer Auktion kann es sein das in den leztten Sekunden 300 Menschen klicken. Bei jedem Klick würde dieses Array verändert werden (das was bei mir aktuell IN der While-Schleife steht).

In der While-Schleife ist es falsch, wenn das Stück Code, das Du uns vor den Latz geknallt hast, Bestandteil eines (jedes!) Client-Prozesses ist.

Was passiert wenn 2 das gleichzeitig tun, ist denke ich klar.

Klar, derjenige, der zu spät kommt, muss warten in einer Schleife. Je nachdem, wie die Speicher(zugriffs)verwaltung, in deren Hoheitsbereich die Methode Memcache::add() gehört, die einzelnen Anforderungen behandelt.

Als Expiration Time hast Du 1 Sekunde angegeben. Für einen reinen Konfliktschutz sollte das genügen, wenn der Zyklus aus den folgenden Komponenten besteht:

-   Besorgen einer Sperre, incl. Abfrage, ob es schon eine gibt.
    Die beiden Schritte müssen vom zuständigen System atomar gekapset sein

-   Abfrage des alten Wertes, der durch das Semaphor (die Sperre) geschützt wird

-   Manipulation des Wertes
    incl, Zurückschreiben in den Shared Memory

-   Aufheben der Sperre.

Je nachdem, ob die Sperrfunktion selber dabei BLOCKING arbeitet, also solange das Programm anhält, bis sie Erfolg hatte (wie es z.B. flock() in der einfachsten Anwendung tut), oder ob sie NON_BLOCKING arbeitet, muss/kann man dies selber berücksichtigen im Programmfluss.

Die Schleife, die ich Dir angedeutet habe, hat nur dann Sinn, wenn sie im Schleifenkörper ein Sleep() (oder in Deinem Fall ein uSleep() http://de3.php.net/manual/en/function.usleep.php enthält, das die Wartezeit anderen Prozessen zur Verfügung stellt. Üblicherweise bedeuten Sleep() und uSleep() bei PHP dem Prozessor (fast) keine Last. Das ist die Voraussetzung, dass Du sie hier sinnvoll einsetezen kannst.

Also so wie ich es gemacht habe geht es gar nicht?

Nein, es ist verkehrt herum.

Liebe Grüße aus dem schönen Oberharz

Tom vom Berg

--
 ☻_
/▌
/ \ Nur selber lernen macht schlau
http://bergpost.annerschbarrich.de