Ich beschäftige mich seit ein paar Monaten mit Python und konnte bis dato alle auftauchenden Fragen mittels Google & Co. auch ohne eigene Thread-Eröffnung lösen. Jetzt allerdings ist anscheinend der Zeitpunkt gekommen, wo ich mit meinem Latein endgültig erstmal am Ende bin.
Mein derzeitiges Projekt ist ein kleines ( also nicht öffentliches, sondern nur für den Freundeskreis ) Browserspiel ( nicht, dass es davon nicht schon reichlich Auswahl gäbe, aber selber machen ist auch mal was ). Soll dann auch nicht auf einem root laufen ( wäre wohl gelinde gesagt ein leichter Overkill, außerdem wäre das Anschaffen eines Rootservers bei meiner derzeitigen Kenntnislage wohl grob fahrlässig ), sondern ein Kumpel hat nicht-kostenlosen Webspace, auf dem Python lauffähig ist.
Ich habe - vielleicht jetzt rückblickend gesehen ein Fehler - mich dafür entschieden, nicht auf "vorgefertigte" Module für mySQL etc. zurückzugreifen, sondern ein eigenes Modul anzufertigen, dass die nötigen Such/Lese/Schreib-Funktionen für den letztlich wohl eher übersichtlichen Datenbestand beinhaltet.
Für eine Tabelle ( z.B. mit den Datensätzen für die Accounts ) wird eine entsprechende Datei angelegt. Um nun zu verhindern, dass verschiedene Zugriffe zur gleichen Zeit auf dieselbe Tabelle stattfinden, soll das erste Byte Auskunft darüber geben, ob die Daten gerade in Benutzung sind oder nicht, also nach dem Schema
"0": frei
"1": belegt, nicht stören
Dieses Byte wird immer erst geprüft und gegebenenfalls etwas gewartet, ehe ein erneuter Zugriffsversuch erfolgt.
Code: Alles auswählen
Pseudocode:
Funktion Lesen(parameter):
tabelle = open(tabellenname, "rb+")
Solange [erstes Byte der Datei als ISO 8859-1] == "1": #prüfe, ob Datei "frei ist"
ein kleines bisschen Abwarten
ansonsten:
erstes Byte auf "1" schreiben #Datei als besetzt markieren
Anfrage abarbeiten
erstes Byte wieder auf "0" schreiben #fertig
Instanz 1 wird nach der if-Bedingung in Zeile 6, aber noch vor dem Setzen des Bytes auf "1" kurzfristig schlafen gelegt. Bevor es weitergeht, läuft Instanz 2 mindestens genauso weit.
Jetzt meinen beide Instanzen, dass die Datei frei ist, und legen quasi parallel los. Die Folgen reichen von "gar nichts passiert" bis "alles zerschossen". Das jedenfalls haben simple Versuche meinerseits bestätigt.
Nun kam mir das Stichwort "thread-sicher" in den Sinn, also Google etc. angeschmissen und gesucht. Ergebnis: Das grundlegende Problem ist zwar weit bekannt, allerdings beziehen sich die Lösungsansätze ( "mutexe", "semaphoren" etc. ) anscheinend immer auf den Fall, dass innerhalb einer ausgeführten "Instanz eines Scripts" Multithreading betrieben werden soll, nicht dass mehrere Instanzen auf dieselben Daten zugreifen wollen ( mit "Instanzen eines Scripts" meine ich, wenn man ganz doof ausgedrückt auf eine .py doppelklickt und das mehrmals hintereinander, noch bevor das Erste fertig ist ).
Ich könnte ja jetzt sagen "gut, dann mache ich das eben doch mit SQL und werfe meine bisherige Arbeit weg", aber das hat was davon, das Problem unter den Teppich zu kehren, statt es zu lösen...
Als allererstes das Byte auf "1" setzen, damit die Datei in jedem Fall auf "belegt" steht, bringt ja nichts. Wenn ich es überschreibe, ohne es je gelesen zu haben, werde ich auch selbst nie erfahren, auf was es denn ursprünglich gestanden hat und ob ich nun weiter verfahren darf oder nicht.