nur eine Instanz eines Skripts

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Hallo

ich möchte sicherstellen, dass ein Skript nur einmal läuft, es also nicht parallel ein 2. Mal ausgeführt wird.

Gibt es da einen eleganten offiziellen Weg?
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Theoretisch könnte man beim Start nachsehen, ob der Prozess schon existiert.
Praktisch geht's wohl einfacher, indem man eine lock Datei nutzt.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Hallo auch

Zu Deiner Frage:
jbs hat geschrieben:Gibt es da einen eleganten offiziellen Weg?

Antwort: Leider nein.

Es gibt lediglich Lösungsansätze. Und die unterscheiden sich auch noch teils von Plattform zu Plattform.

>>Masaru<<
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Es gibt unter Linux im GNOME-Umfeld die libunique, die genau diese Funktionalität bietet und es sogar ermöglicht, zwischen den gestarteten Prozessen Daten auszutauschen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Es hat handelt sich leider um Windows :(.
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Tjoa ... da gibt es (nur) Alternativ-Lösungen.

Eine wäre das Durchstöbern der laufenden Windows Prozesse via pywin32, wo Du dann prüfen könntest ob Dein Script (Pfad/Namenstechnisch) bereits läuft.

Eine andere wäre das Verwenden einer Semaphore-(Lock)-Datei/RegistryEintrag/DB-Locks/etc.pp

>>Masaru<<
lunar

Ich würde einen Server auf einem beim Start zufällig ausgewählten, freien Port auf 127.0.0.1 verwenden. Die Portnummer schreibt das Programm in eine Datei in "~". Beim Start liest das Programm den Port aus der Datei, verbindet sich zum Server und sendet eine definierte Nachricht. Falls eine ebenfalls definierte, positive Antwort zurück kommt, läuft das Programm bereits, ansonsten läuft es nicht.

Diese Lösung ist mit den Mitteln der Standardbibliothek einfach umzusetzen, plattformunabhängig, und flexibel. Die Umsetzung kann auf verschiedenen Wege erfolgen, von einfachen Sockets für eine einfache Überprüfung bis hin zu XMLRPC für komplexere IPC. Ich würde wohl letzteres wählen, weil es schnell und einfach zu programmieren ist.
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

... das ist ja krank :shock:

In restriktiv stark eingeschränkten Windows Umgebungen mit Firewalls ist das ja bestimmt ein richtig schöner Overkill und Self-Knockout :D

*hehe* ich werds mir aber mal merken, ist ne richtig abgef***t geniale Alternative.

>>Masaru<<
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

jbs hat geschrieben:ich möchte sicherstellen, dass ein Skript nur einmal läuft
Hallo jbs!

http://www.python-forum.de/topic-8282.html

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Komischerweise kann ich in dem von Gerold verlinkten Thread nicht antworten, hier hingegen schon. Was ich sagen wollte, war: Ich schlage die Methoden __enter__ und __exit__ vor; entweder als syntaktischen Zucker (also shortcut) für create_lock und delete_lock oder als Ersatz.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Danke Gerold!

Das mit dem ``with`` hatte ich auch schon überlegt. Ich würde noch ``__nonzero__`` definieren.

Und ich hatte gedacht, man könnte über den XMLRPC auch noch eine Aktion im laufenden Skript ausführen. Das heißt man könnte das Fenster enticonisieren.
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

derdon hat geschrieben:Komischerweise kann ich in dem von Gerold verlinkten Thread nicht antworten...
Liegt an phpBB und tritt immer dann auf, wenn zuviel code im Beitrag steckt...

Ich hab die letzte Version von FirstStart ins Wiki ausgelagert: http://wiki.python-forum.de/Programm%20Lock

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Bin über ein paar Sachen gestolpert. Ein return nach einem raise ist eher weniger Sinnvoll oder? :D

Ich überarbeite das Skript und hoffe es läuft danach.
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Und warum nimmt `set_access_rights()` `files` an, ohne was damit zu machen? Irgendwie kommt mir die ganze Funktion seltsam vor...

Warum, will man es in `do_command()` "richtig" machen und setzt `shell=True`?
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

jbs: Ich würde mich freuen, wenn du deine überarbeitete Version mit in den Wiki-Artikel packst.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

lunar hat geschrieben:Ich würde einen Server auf einem beim Start zufällig ausgewählten, freien Port auf 127.0.0.1 verwenden. Die Portnummer schreibt das Programm in eine Datei in "~". Beim Start liest das Programm den Port aus der Datei, verbindet sich zum Server und sendet eine definierte Nachricht. Falls eine ebenfalls definierte, positive Antwort zurück kommt, läuft das Programm bereits, ansonsten läuft es nicht.
Man sollte dabei überlegen, ob verschiedene user das gleiche Programm starten dürfen oder nicht. Firefox kann etwa jeder User nur einmal starten aber es darf mehrmals im System laufen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Ich habs mal ein wenig aufgeräumt. Den XMLPRC Server habe ich rausgenommen, dafür wollte ich eine eigene Klasse schreiben.

Mal der aktuelle Stand: http://paste.pocoo.org/compare/165476/165474/

Dadurch verkürzt es sich auf:

Code: Alles auswählen

from rununique import RunUnique
from time import sleep

with RunUnique() as unique:
    if unique:
        for i in range(10):
            print i
            sleep(1)
    else:
        print 'x'
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Zum XMLRPC: Würdet ihr eher einen zufälligen Port nehmen und den dann wie beim PID abpeichern oder den Port aus dem Namen der Applikation generieren, wie es bisher der Fall war?
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Den Namen der App als Salz für den SHA1-Hash der PID + zufälliger Zahl nehmen und von dessen hexdigest-Wert die ersten 4 Ziffern extrahieren

8)
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Code: Alles auswählen

''.join(c for c in hashlib.sha1('myapp').hexdigest() if c.isdigit())[:4]
so?
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Antworten