Hallo Ich möchte vermeiden, dass ein Python Script mehr als einmal läuft. Wie kann ich kontrollieren, ob es bereits gesterten wurde?
Schreib ne Datei ins /tmp. So fange ich auch Kernelexceptions im Toplevelscript ab, wenn die Childs mal verrecken.
lockfile/lockdir? prozesse auf listen und schaun ob es da vorhanden ist?
Moin, guggsdu hier: Windows: http://code.activestate.com/recipes/474070-creating-a-single-instance-application/ Linux: https://stackoverflow.com/questions/380870/python-single-instance-of-program oder https://raspberrypi.stackexchange.com/questions/22005/how-to-prevent-python-script-from-running-more-than-once HTH Baku
Rüdiger schrieb: > Ich möchte vermeiden, dass ein Python Script mehr als einmal läuft. Wie > kann ich kontrollieren, ob es bereits gesterten wurde? Du musst selbst ein systemweites Objekt erzeugen, welches das möglich macht. Möglich macht es das, wenn für dieses systemweite Objekt ein IPC-Mechanismus existiert, der "erzeuge, wenn noch nicht vorhanden" realisiert und ein entsprechendes Ergebnis zurück gibt. Es gibt sowohl unter Windows als auch unter Linux mehrere solcher IPC-Mechanismen. Die Wahl des am besten geeigneten hängt eigentlich nur davon ab, was das Script tun soll. Ist also dein Job, denn nur du kennst es... So ist das mit der Salamitaktik: Das Ende der Wurst landet schnell wieder in der eigenen Fresse und man ist so schlau wie zuvor...
Unter Linux schaut man was für ein Init System (init.d, upstart usw.) von der Distribution genutzt wird und nutzt dann dieses. lockfiles o.ä. haben das Problem dann sie bestehen bleiben wenn das Script gekillt.
test schrieb: > lockfiles o.ä. haben das Problem dann sie bestehen bleiben wenn das > Script gekillt. Lockfile ins /tmp und das /tmp auf die RAM-Disk ...
roks schrieb: > test schrieb: > lockfiles o.ä. haben das Problem dann sie bestehen bleiben wenn das > Script gekillt. > > Lockfile ins /tmp und das /tmp auf die RAM-Disk ... Und wenn das Scipt abstürzt bootet man den Rechner neu, so fürs echte Windows feeling ;-) Die Linux Init Systeme bieten hier sehr viele Vorteile, es macht Sinn den eigenen Daemon (was das Script letztendlich ist) darüber einzubinden.
test schrieb: >> Lockfile ins /tmp und das /tmp auf die RAM-Disk ... > > Und wenn das Scipt abstürzt bootet man den Rechner neu, so fürs echte > Windows feeling ;-) Oder man löscht die Datei einfach. Gute bash Scripts setzen halt mit "trap" eine cleanup funktion. In C hat man signal handler. Bei python weiss ich jetzt nicht, da muss man halt schauen wie das Modul dafür, welches man nimmt, reagiert. test schrieb: > Die Linux Init Systeme bieten hier sehr viele Vorteile, es macht Sinn > den eigenen Daemon (was das Script letztendlich ist) darüber > einzubinden. Das muss aber nicht zwangsläufig das init system übernehmen. Ins rc system passt es schon eher. Aber andere Tools & Hilfsprogramme können das auch, z.B. start-stop-daemon. Bei init scripts kann man auch einen Interpreter wählen, der das alles übernimmt, z.B. mein https://github.com/Daniel-Abrecht/unitscript, oder init-d-script in debian. Man könnte auch lsof verwenden, dann darf man aber die inode nummer des Skripts nicht versehentlich ändern, während es läuft, und man kann dann halt wirklich nur eine Instanz haben. Würd ich aber nicht empfehlen:
1 | #!/bin/bash
|
2 | |
3 | if lsof -F p "$0" | grep "p" | grep -vE "p$$" | grep -q .; |
4 | then
|
5 | echo "Already running!" |
6 | exit 1
|
7 | fi
|
8 | |
9 | echo "Started!" |
10 | sleep 4
|
11 | echo "Stopped!" |
Unter Linux könntest du mit fcntl.lockf ein lock auf dein python script setzen und das dann Prüfen wenn es da ist läuft dein script gerade. ungefähr so:
1 | #! /usr/bin/env python
|
2 | import os |
3 | import fcntl |
4 | |
5 | def exclusive(): |
6 | # open own script to get a lock on it
|
7 | lfd = os.open(__file__, os.O_RDWR) |
8 | try: |
9 | # not blocking request for the lock
|
10 | fcntl.lockf(lfd, fcntl.LOCK_EX | fcntl.LOCK_NB) |
11 | except IOError: |
12 | print('other instance is running, DIE') |
13 | return
|
14 | else: |
15 | input('Here we are exclusive') |
16 | # relase the lock
|
17 | fcntl.lockf(lfd, fcntl.LOCK_UN) |
18 | |
19 | if __name__ == '__main__': |
20 | exclusive() |
21 | print('exit') |
durch das fcntl.LOCK_NB geht der code in die exception und du weißt das auf dem system gerade eine andere instanze des script läuft. Das ganze sollte unter Linux und dem MAC gehen für Windows musst du mal googlen was es da für Funktionen gibt welche einen teil einer Datei exklusive locken.
DPA schrieb: > test schrieb: >>> Lockfile ins /tmp und das /tmp auf die RAM-Disk ... >> >> Und wenn das Scipt abstürzt bootet man den Rechner neu, so fürs echte >> Windows feeling ;-) > > Oder man löscht die Datei einfach. Gute bash Scripts setzen halt mit > "trap" eine cleanup funktion. In C hat man signal handler. Bei python > weiss ich jetzt nicht, da muss man halt schauen wie das Modul dafür, > welches man nimmt, reagiert. Das ist noch nicht mal notwendig, man kann es auch so machen wie Mozilla (Firefox, Thunderbird) mit seiner parent.lock Sperrdatei im Profil: Die Datei bleibt während der Lebensdauer des Prozesses schreibend geöffnet (und dadurch gesperrt). Das erneute Anlegen der Datei durch einen weitren Prozess schlägt so lange fehl, wie der ursprüngliche Prozess noch läuft -> neuer Prozess erkennt das und beendet sich weil er keine Sperre bekommt. Dadurch ist ein Aufräumen der Lockdatei nicht notwendig, wenn der Prozess abstürzt kann der nächste Prozess sie überschreiben, da das OS die Sperre dann aufhebt. Und aufräumen einer 0Byte Datei ist auch nicht zwingend notwendig.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.