Programm Kontrolle

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.
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

@BlackJack, wußte nicht, daß 'prog.cmdline' auch geht.

Ist dies aktzeptabel?

Code: Alles auswählen

    for prog in psutil.process_iter():
        if programm[:15] in prog.name or programm in prog.cmdline:
            if int(prog.pid) != int(pid_start):
                pid_current = prog.pid
                break
        else:
            pid_current = None
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hast Du mein Posting überlesen? Da steht ja immer noch `int(prog.pid)`... :!:

Der `else`-Zweig ist doch auch wieder unschön:

Code: Alles auswählen

...
else:
    pid_current = None
Du musst `pid_current` *vor* der Schleife an `None` binden; das ist doch viel effizienter, als in *jedem* Durchlauf der Schleife!

Und natürlich "geht" `prog.cmdline` - `prog.pid` "geht" ja auch! Was hast Du denn gedacht, was `prog` für ein Objekt ist? Und wie bist Du auf `prog.pid` gekommen, ohne zu erkennen, dass logischer Weise *alle* Attribute und Properties eines Objekt-Typen auf diesem aufrufbar sind? Auch dies ist (leider) wieder ein Beispiel für Deine Art und Weise, *nicht* richtig / gründlich / ausreichend über Code nachzudenken, den Du schreibst :!:

Ich denke, wenn Du das nicht schnell änderst, dann wirst Du mit mir alleine als Helfer auskommen müssen in naher Zukunft... denn im Moment ist es einfach nur frustrierend zu sehen, dass praktisch *keine* grundlegenden Tipps von Dir umgesetzt werden; damit meine ich Dinge, wie das allgemeine Vorgehen, das Lernen von Grundlagen, das Ausprobieren und Entwickeln von Ausdrücken in einer Shell, usw.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Hallo Hyperion,
Nach meinem Post bin ich gleich auf die nächste Seite geleitet worden, daher habe ich Deinen letzten Post erst jetzt gesehen.
War keine böse Absicht dahinter, Danke für Deinen Hinweis.

Das mit 'pid_current = None' dachte ich auch, daß die Position vorher besser war. Habe mich da irgendwie verunsichern lassen. Das werde ich sofort wieder berichtigen.

So, nun zu Deinem letzten Post.
Die erste Ausgabe sieht gut aus und sehe jetzt auch daß das int-Format 'int(pid_start)' hier unnötig ist.

Ich suche die PID('s), die bei einem evtl. Doppelstart des Programms entstanden sind.

Mit Deinen Erklärungen, vermute ich mal, daß ich schon mit meinem letzten Post richtig lag, JA?
Aktueller Stand:

Code: Alles auswählen

    pid_start = psutil.Process(os.getpid()).pid

    pid_current = None

    for prog in psutil.process_iter():
        if programm[:15] in prog.name or programm in prog.cmdline:
            if prog.pid != pid_start:
                pid_current = prog.pid
                break
Du meinst, ich probiere nur das Programm als Ganzes und nicht einzelne Punkte, da irrst Du Dich.
Ich nehme mir einzelne Zeilen vor und schaue nach der Ausgabe. Ich weiß, daß ich noch zu kompliziert denke, was bei Python eigentlich so nicht sein muß. Vielleicht ein Problem was dazu beiträgt, sind meine Nicht-Englischkenntnisse, sonst wären die englischsprachigen Seiten für mich besser verständlich. Ich versuche englischsprachige Texte mit dem Google-Übersetzter, mir übersetzen zu lassen. Oft ist dies dann so verständlich, daß ich mir einen Reim drauf machen kann. Hier allerdings hat er versagt:
Return an iterator yielding a Process class instances for all running processes on the local machine. This should be preferred over doing for pid in psutil.get_pid_list(): psutil.Process(pid) as it safe from race conditions.
Vielleicht könntest Du mir den zweiten Satz richtig übersetzen?

Ich arbeite mit Geany, dort erhalte ich normale Ausgabe, Fehler-Codes und -Beschreibungen. Manche Dinge probiere ich auch auf der Konsole aus. Ich habe auch ipython, ein Terminal für Python, das habe ich aber bis jetzt selten genutzt.

Es tut mir Leid, daß ich so frustrierend auf Euch wirke. Ich verstehe Euch wirklich, daß dies kein Dauerzustand sein kann viele mich als 'hoffnungslos' abstempeln ...

Ich will keine Versprechungen abgeben, hoffe aber für mich und Euch, daß sich dies bessert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Nobuddy hat geschrieben: Das mit 'pid_current = None' dachte ich auch, daß die Position vorher besser war. Habe mich da irgendwie verunsichern lassen.
Du darfst Dich nicht verunsichern lassen, sondern musst einfach darüber nachdenken. Frage Dich stets: Was passiert hier im Code? Wenn Du eine Schleife hinschreibst, dann frage Dich, "Was passiert in jedem Durchlauf?". Genau an diesem Punkt erkennst Du dann, dass es keinen Sinn macht, bei quasi jedem Durchlauf `pid_current` erneut an `None` zu binden - oder? ;-)

Du bist sicher nicht zu dumm, dieses nachzuvollziehen! Dir fehlt es an der Fähigkeit, Code genau so zu betrachten, wie ich es Dir gerade vorgeführt habe. Und genau daran musst Du arbeiten :-)
Nobuddy hat geschrieben: Hier allerdings hat er versagt:
Return an iterator yielding a Process class instances for all running processes on the local machine. This should be preferred over doing for pid in psutil.get_pid_list(): psutil.Process(pid) as it safe from race conditions.
Vielleicht könntest Du mir den zweiten Satz richtig übersetzen?
Naja, ich versuche es mal - auch wenn mein Englisch nicht gerade perfekt ist ;-)
"Gibt einen Iterator zurück, der ein Exemplar der `Process`-Klasse für alle laufenden Prozesse der lokalen Maschine liefert. Dieses Vorgehen sollte man gegenüber `for pid in psutil.get_pid_list(): psutil.Process(pid)` bevorzugen, da es sicher gegenüber "race conditions" ist.

Du hast den Aufruf an sich aber ja auch richtig "interpretiert".

Ich kapiere aber Deinen ganzen Ansatz noch nicht - hatte deets Dir nicht eine fertige Lib empfohlen, mit der man Lockfiles anlegen kann? Und wenn Du diese nicht verwenden magst, wäre es doch zielführender via `fcntl`-Modul eine Lockdatei zu erstellen...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
deets

Hyperion hat geschrieben: Ich kapiere aber Deinen ganzen Ansatz noch nicht - hatte deets Dir nicht eine fertige Lib empfohlen, mit der man Lockfiles anlegen kann? Und wenn Du diese nicht verwenden magst, wäre es doch zielführender via `fcntl`-Modul eine Lockdatei zu erstellen...
Nobody knows but Nobuddy. Statt 3 Zeilen zu schreiben die das Problem loesen, lieber 3 Wochen fuer 30 Zeilen verbraten, die das Problem *nicht* loesen. Aber jeder nach seiner Fasson...

http://www.youtube.com/watch?v=Ebr6FbCGoTE
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Hyperion hat geschrieben: Ich kapiere aber Deinen ganzen Ansatz noch nicht - hatte deets Dir nicht eine fertige Lib empfohlen, mit der man Lockfiles anlegen kann? Und wenn Du diese nicht verwenden magst, wäre es doch zielführender via `fcntl`-Modul eine Lockdatei zu erstellen...
Wahrscheinlich war ich zu arg auf mein Vorhaben fixiert, so daß ich vor lauter Wald, keine Bäume mehr sah. :wink:
deets hat geschrieben:Nobody knows but Nobuddy. Statt 3 Zeilen zu schreiben die das Problem loesen, lieber 3 Wochen fuer 30 Zeilen verbraten, die das Problem *nicht* loesen. Aber jeder nach seiner Fasson...
Ja, das ist oft mein Problem. Ich will wirklich versuchen, von meiner Kompliziertheit weg zukommen, das Leben könnte ja dann so einfach sein ... :wink:

Das mit dem `fcntl`-Modul, dürfte wohl tatsächlich die einfachste Lösung sein, muß mich da nur nochmal durchlesen!

Die fertige Lib, war mir zu kompliziert, damein Englisch .... :K
deets

Nobuddy hat geschrieben:
Das mit dem `fcntl`-Modul, dürfte wohl tatsächlich die einfachste Lösung sein, muß mich da nur nochmal durchlesen!

Die fertige Lib, war mir zu kompliziert, damein Englisch .... :K
Nee, is klar. Das fcntl Modul (mit englischer Dokumentation) welches ein ziemlich tiefes Verstaendnis von den beteiligten Systemcalls verlangt vs. ein Modul, das dir das in 3 Zeilen wegabstrahiert + sogar Beispielcode in den Tests hat, den ich verlinkt habe....

Dir ist nicht zu helfen.
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

@deets, anhand dieses Links http://aktuell.de.selfhtml.org/artikel/ ... python.htm, sieht das nicht ganz so kompliziert aus, aber ich kann mich auch täuschen.

Es wurde hier in diesem Thread schon sehr viel, vielleicht auch schon zu viel geschrieben, so daß ich mich nur noch entfernt an diese Lib erinnere ...

Es gibt i.d.R. immer mehrere Möglichkeiten Dinge umzusetzen und vieles sieht man oft zu kompliziert, wie auch bei mir.
Es ist ein Lernprozess, der beim Einen schneller und beim Anderen eben langsamer voran geht.
Fehler vermeiden bringt nur die Praxis und Erfahrung, die man in so einem Prozess durch schreitet.
Toleranz bringt den Vorteil, andere auch Fehler machen zu lassen, auch das gehört zum Lernprozess für beide, der was lernen und der der etwas weitergeben möchte. :wink:
deets

Nobuddy hat geschrieben:@deets, anhand dieses Links http://aktuell.de.selfhtml.org/artikel/ ... python.htm, sieht das nicht ganz so kompliziert aus, aber ich kann mich auch täuschen.
Ich wuerde mal sagen angesichts deiner bisherigen Schwierigkeiten - ja, da taueschst du dich. Und in jedem Fall ist es komplizierter als die abl.util.LockFile-Variante. Die ist ja genau deswegen geschrieben worde, um den OS-abhaengigen und je nach Anwendungsfall unterschiedlichen Einsatz des fcntl-Moduls zu abstrahieren...

Es wurde hier in diesem Thread schon sehr viel, vielleicht auch schon zu viel geschrieben, so daß ich mich nur noch entfernt an diese Lib erinnere ...
Das kann ja gut sein. Dann wundere ich mich aber, wieso du sagst "Die fertige Lib war mir zu kompliziert". Wo du dich doch ganz entfernt erinnern kannst?!?
Es ist ein Lernprozess, der beim Einen schneller und beim Anderen eben langsamer voran geht.
Fehler vermeiden bringt nur die Praxis und Erfahrung, die man in so einem Prozess durch schreitet.
Toleranz bringt den Vorteil, andere auch Fehler machen zu lassen, auch das gehört zum Lernprozess für beide, der was lernen und der der etwas weitergeben möchte. :wink:
Es gibt einen Unterschied zwischen einem Lernprozess, und dem ignorieren von Rat. Niemand hindert dich daran, alles selbst zu machen. Stellt sich dann die Frage, *warum* du dann hier um Rat fragst. Weil du dir doch vielleicht aus den Erfahrungen anderer schneller Erfolg beim eigenen Lernen versprichst? Wieso ignorierst du dann aber willkuerlich was man dir vorschlaegt? Wenn du die Erfahrung haettest, die dargebotenen Ansaetze zu vergleichen und nach informierten Kriterien abzulehnen wuerdest du die Fragen wahrscheinlich erst gar nicht stellen.... so aber zeigt sich Willkuer oder Ignoranz. Ich unterstelle dir da keine Boshaftigkeit. Nur fragwuerdige Beliebigkeit in deinem Vorgehen.
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

@deets, ich wollte Dich keinesfalls irgendwie angreifen.
Willkuer oder Ignoranz sind schon harte Worte, hoffe daß ich Dich irgendwann vom Gegenteil überzeugen kann. :wink:
deets

Nobuddy hat geschrieben:@deets, ich wollte Dich keinesfalls irgendwie angreifen.
Willkuer oder Ignoranz sind schon harte Worte, hoffe daß ich Dich irgendwann vom Gegenteil überzeugen kann. :wink:
Nix einfacher als das - folge einfach mal den Ratschlägen von mir & anderen hier, die dir schon vor X Seiten gegeben wurden. Anstatt dich in andere Dinge zu verbeißen und noch eine extrarunde zu drehen...
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

@deets, daran werde ich arbeiten.

Zu 'fcntl', habe ich folgendes am Anfang des Programms erstellt:

Code: Alles auswählen

PROGRAMM = 'lbestellorder.py'

# Programm wird bei zweitem Starten des Programms gesperrt.
# Mehrfachstart wird verhindert
f = open(PROGRAMM, "r+")
fcntl.flock(f.fileno(), fcntl.LOCK_EX)
Funktioniert prima, ein Mehrfachstart ist so nicht mehr möglich (nach meinen Testś).

Was nicht funktioniert ist, wenn ich dies in eine Funktion packe:

Code: Alles auswählen

PROGRAMM = 'lbestellorder.py'

def prog_barrier(PROGRAMM):
    # Programm wird bei zweitem Starten des Programms gesperrt.
    # Mehrfachstart wird verhindert
    f = open(PROGRAMM, "r+")
    fcntl.flock(f.fileno(), fcntl.LOCK_EX)

prog_barrier(PROGRAMM)
Da Du angesprochen hast, daß dies nicht so einfach ist, wie es aussieht, würde ich mich über ein Info über die 'versteckten' Gefahren bzw. Probleme freuen.

Das mit der Lib werde ich mir nochmals genauer anschauen.
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

fcntl funktioniert soweit, daß es das betreffende Programm dann sperrt, sehe aber inzwischen die ein:
deets hat geschrieben: Ich wuerde mal sagen angesichts deiner bisherigen Schwierigkeiten - ja, da taueschst du dich. Und in jedem Fall ist es komplizierter als die abl.util.LockFile-Variante. Die ist ja genau deswegen geschrieben worde, um den OS-abhaengigen und je nach Anwendungsfall unterschiedlichen Einsatz des fcntl-Moduls zu abstrahieren...
Also wenn, dann doch die Lib ... :wink:
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

So, habe mir von hier http://hg.ableton.com/abl.util/src/07b1 ... ockfile.py, den kompletten Ordner 'abl.util' abgespeichert.

Wie gehe ich jetzt weiter vor?
deets

das war falsch. du musst das ding so installieren wie andere 3rd-party-packages auch - via easy_install oder pip zb. psutil hast du doch auch irgendwie installiert bekommen, analog dazu.
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Ok, wenn ich das richtige Paket habe, sollte es 'python-lockfile' sein.
Das habe ich installiert.

Mal schauen, wie es jetzt weiter geht!

Hmm ... und dann verließen sie ihn ... :K
deets

Nö, das Paket heißt abl.util. Aber wenn Python-lockfile existiert, dann tut das vll was ähnliches. Doku lesen, sollte ja mitinstalliert sein oder seinbar.
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Das Paket abl.util ist in Kubuntu 12.04 nicht vorhanden.

Code: Alles auswählen

print lockfile.__doc__
gibt dies aus:
lockfile.py - Platform-independent advisory file locks.

Requires Python 2.5 unless you apply 2.4.diff
Locking is done on a per-thread basis instead of a per-process basis.

Usage:

>>> lock = FileLock('somefile')
>>> try:
... lock.acquire()
... except AlreadyLocked:
... print 'somefile', 'is locked already.'
... except LockFailed:
... print 'somefile', 'can\'t be locked.'
... else:
... print 'got lock'
got lock
>>> print lock.is_locked()
True
>>> lock.release()

>>> lock = FileLock('somefile')
>>> print lock.is_locked()
False
>>> with lock:
... print lock.is_locked()
True
>>> print lock.is_locked()
False
>>> # It is okay to lock twice from the same thread...
>>> with lock:
... lock.acquire()
...
>>> # Though no counter is kept, so you can't unlock multiple times...
>>> print lock.is_locked()
False

Exceptions:

Error - base class for other exceptions
LockError - base class for all locking exceptions
AlreadyLocked - Another thread or process already holds the lock
LockFailed - Lock failed for some other reason
UnlockError - base class for all unlocking exceptions
AlreadyUnlocked - File was not locked.
NotMyLock - File was locked but not by the current thread/process
Ich habe dies dann mal versucht umzusetzen.

Bei

Code: Alles auswählen

lock = FileLock('somefile')
habe ich dies

Code: Alles auswählen

lock = FileLock('/home/user/meinfile.py')
sowie

Code: Alles auswählen

lock = FileLock('meinfile.py')
gemacht, dabei kommt dann als Meldung
NameError: name 'FileLock' is not defined
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Ein from lockfile import FileLock sollte Abhilfe schaffen.
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Hallo jerch,
Danke für die Info, jetzt kommt keine Fehlermeldung mehr! :wink:

Dann kann ich mir mal dies genauer anschauen.
Antworten