Gleichzeitiger Zugriff auf Datei verhindern

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo

    Ich bekomme einen Error, wenn zwei laufende Skripte gleichzeitig auf eine pickle Datei zugreifen wollen.

    Kann ich das irgendwie verhindern dass die gleichzeitig darauf zugreifen?

  • Also das erste Skript ist:

    [code=php]
    def read():
    with open('/home/pi/time.pkl') as f:
    t = pickle.load(f)
    print(t)
    return t

    def write():
    with open('/home/pi/time.pkl','wb') as f:
    value = time.time()
    pickle.dump(value,f)

    while True:
    if time.time() - read() >= max:
    print "LED ein!"
    GPIO.output(24,GPIO.HIGH)
    time.sleep(1)
    GPIO.output(24,GPIO.LOW)
    write()
    time.sleep(1)[/php]


    Das zweite Skript wird von einem Sensor aufgerufen und kommt deshalb unregelmässig:

    [code=php]

    import time
    import pickle

    def write():
    with open('/home/pi/time.pkl','w') as f:
    value = time.time()
    print value
    pickle.dump(value,f)

    write()[/php]

    Ich bekomme dann den Error:

    [code=php]Traceback (most recent call last):
    File "read_time.py", line 53, in <module>
    if time.time() - read() >= max:
    File "read_time.py", line 28, in read
    t = pickle.load(f)
    File "/usr/lib/python2.7/pickle.py", line 1378, in load
    return Unpickler(file).load()
    File "/usr/lib/python2.7/pickle.py", line 858, in load
    dispatch[key](self)
    File "/usr/lib/python2.7/pickle.py", line 880, in load_eof
    raise EOFError
    EOFError[/php]

    Ich glaube dass der kommt weil beide Skripte gleichzeitig auf die time.pkl Datei zugreifen wollen ... :s

    Danke für Tipps

  • Wenn ich das richtig verstehe dann verwendest du die Datei einfach nur um den aktuellen Timestamp rein zu schreiben, oder? :s Warum du das machst versteh ich allerdings noch nicht...

    Anstatt diesen Wert zu verwenden würde ich die 'modification time' der Datei abrufen.

    Also:
    Dein Sensor-Script schreibt einfach 'irgend etwas' in die Datei. Dein 2.Script prüft dann regelmässig besagte "last modification time" der Datei und muss somit nicht mehr direkt die Datei öffnen und auslesen:

    [code=php]import os.path, time

    while True:
    if os.path.isfile('/home/pi/time.pkl'):
    lastTime = os.path.getmtime('/home/pi/time.pkl')
    if time.time() - lastTime >= max:
    print "LED ein!"
    GPIO.output(24,GPIO.HIGH)
    time.sleep(1)
    GPIO.output(24,GPIO.LOW)
    time.sleep(1)
    [/php]

    Allerdings würde diese while dann ständig anschlagen und die LED jede Sekunde erneut eingeschaltet werde da die Prüfung ">= max" kein Ende findet.
    Besser wäre:
    [code=php]import os.path, time

    lastTime=None

    while True:
    if os.path.isfile('/home/pi/time.pkl'):
    if lastTime and (os.path.getmtime('/home/pi/time.pkl') <> lastTime):
    print "LED ein!"
    GPIO.output(24,GPIO.HIGH)
    time.sleep(1)
    GPIO.output(24,GPIO.LOW)
    lastTime = os.path.getmtime('/home/pi/time.pkl')
    time.sleep(1)
    [/php]

    Dann schlägt er wirklich nur dann ein mal an wenn die Datei verändert wurde.

  • Danke für die Hilfe meigrafd und bootsmann!

    bootsmann: hab jetzt überall die rb und wb ergänzt. Aber der Error kommt leider immer noch :(

    meigrafd: Genau, er schreibt nur die Zeit da rein. Das Deshalb, weil ich die Zeit vom Sensor irgendwie in das erste Skript bringen muss für den Vergleich >= max. Mir ist da keine Andere Variante bekannt gewesen als dieses pickle.

    Ich verstehe noch nicht ganz was das Zeichen '<>' macht?
    Und wieso hast du das /tmp/time.pkl verwendet bei der zweiten Variante und nicht das /home/pi/time.pkl?

  • Ich verstehe noch nicht ganz was das Zeichen '<>' macht?

    Guckst du: http://www.tutorialspoint.com/python/python_basic_operators.htm

    Und wieso hast du das /tmp/time.pkl verwendet bei der zweiten Variante und nicht das /home/pi/time.pkl?

    Ignorier das. Spielt keine Rolle welche Datei wo liegt.... Hauptsache immer die selbe. War von mir ein 'copy&paste' Fehler..
    Ich nutze generell /tmp/ da das bei mir tmpfs is (sowas wie eine ramdisk) und somit nicht die SD mit unnötigen Schreibvorgängen belastet - dieser Pfad stammt also von meinem Test vorhin, um nicht irgendwelche Vermutungen zu posten sondern tatsächlich funktionierendes...


  • bootsmann: hab jetzt überall die rb und wb ergänzt. Aber der Error kommt leider immer noch :(

    Dann hast du anscheinend es irgendwo noch vergessen, denn so gibt es keinen Fehler:

    Programm 1:

    Programm 2:

  • bootsmann: Ja bei mir hat es zuerst auch keinen Error gegeben, erst nach einiger Zeit, als wahrscheinlich beide Skripte gleichzeitig aufgerufen wurden.
    In deinem Fall mit den beiden while True und sleep(5) ist es doch eher unwahrscheinlich dass beide Skripte gleichzeitig auf die Datei zugreifen, oder sehe ich das falsch?

    meigrafd: Danke, ja das funktioniert. Aber nicht so wie es soll. Denn die LED soll erst Blinken, wenn maxDiff überschritten wurde. Jetzt blinkt sie, sobald der Sensor betätigt wird.
    Ich kann jetzt die lastTime nicht mehr auf die aktuelle Zeit setzten.. Aber ich glaube das alles hast du auch schon gesehen.
    Ich müsste also doch irgendwie in die Datei reinschreiben können.

    Hmm, gäbe es nicht irgend eine andere Variante, mit der der gemeinsame Zugriff Verhindert werden könnte?
    Ich habe auch noch .txt Dateien bei denen ein gemeinsamer zugriff von verschiedenen Skripten aus verhindert werden muss. Aber irgendwie finde ich das keine Idee wie ich das machen kann.. :s
    Oder gibt es ein mutex oder so dass ich verwenden könnte?

    Einmal editiert, zuletzt von Ruben89 (7. Mai 2015 um 22:11)

  • Ich müsste also doch irgendwie in die Datei reinschreiben können.

    Wozu?
    Ich glaub du hast nicht verstanden was da überhaupt passiert...

    Ob du nun den letzten Aufruf des Sensors als unixtimestamp in eine Datei rein schreibst, oder anhand der "last modification time" heraus findest - spielt kaum eine Rolle, nur eben Dein Problem dass 2 Scripts gleichzeitig auf die Datei zugreifen...


    Bevor ich mir jetzt aber die Mühe mache und Dein Problem löse - wäre interessant die Hintergründe bzw das Wieso zu erfahren... Wieso darf nur ein Script schreiben, was macht dieses Script überhaupt, was macht das 2.Script und wieso schreibst du in irgend welchen txt dateien rum?

  • @ meigrafd: Ja du hast recht, das mit der last modification time funktioniert so wie gesagt hast.

    Also ich habe einen Sensor, der ruft bei einer Aktivität das Skript auf welches die Zeit in den Speicher (time.pkl Datei) legt.
    Wenn zu lange keine Aktivität von diesem Sensor vorhanden war, soll das bemerkt werden.
    Dazu möchte ich die Zeit aus der time.pkl Datei lesen mit dem zweiten Skript und diese Zeit mit der aktuellen Zeit vergleichen.

    Deshalb diese Zeile:
    [code=php]if time.time() - lastTime >= max:[/php]

    Aber ich habe das zuerst falsch geschrieben, es muss nicht nur ein Skript in den Speicher schreiben können, sondern beide. Denn wenn das max überschritten wurde, wird wieder die aktuelle Zeit in den Speicher gelegt. Aber nur das zweite Skript mit der Auswertung muss die Zeit auslesen.

    Also beide Skripte schreiben, nur eines liest.
    Ich hoffe das ist einigermassen verständlich :neutral:

    Aber ich weiss nicht recht ob das evtl nicht die richtige lösung ist mit der pickle Datei. Evtl gäbe es da bessere Möglichkeiten?

    Ich habe noch etwas gefunden, dass evtl das Problem mit dem gemeinsamen Zugriff lösen könnte. Ich würde das write() atomar machen, dass es sicherlich nicht unterbrochen wird:

    [code=php]from atomicwrites import atomic_write

    def write():
    with atomic_write('/home/pi/time.pkl', overwrite=True) as f:
    f.write(time.time())[/php]

    Könnte das die Lösung sein?


    mobby: Danke für den Tipp. Ich kenne mich mit Threads leider sehr wenig aus, und ich glaube das würde mir mehr Probleme bereiten als die andere Variante.. :s

  • Ich versteh immer noch nicht wieso das auf diesen Weg versuchst und glaube das es anders besser wäre, aber da ich nicht weiß um welchen Sensor es sich handelt kann ich hier nur raten... Ich glaub du gehst das von der falschen Seite an..

    Um was für einen Sensor handelt es sich?
    Wie ist dieser Sensor angeschlossen?

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!