Seite 6 von 7

Re: Programm Kontrolle

Verfasst: Montag 18. Juni 2012, 08:33
von Hyperion
Denk doch noch mal bitte über dieses nach - ich erwähnte das ja schon einmal:

Code: Alles auswählen

prog_short = '{}'.format(programm[:15])
Sage mir doch mal, welchen Typen `programm` hat - aus Deinen bisherigen Beiträgen schließe ich, dass es sich bereits um einen String handelt. Damit wäre es doch trivial, wie man das *viel* einfacher formulieren kann! Und wenn es kein String wäre, dann wäre es dennoch sinnvoller, hier `str()` zu nutzen, als umständlich die `format`-Methode für die Konvertierung zu "missbrauchen".

Deine Aufgabe ist also folgendes: Öffne eine Python-Shell und belege mal `programm` (ggf. über Copy & Paste) mit einem realen Wert. Dann Arbeitest Du Dich von "hinten nach vorne" durch Deinen Ausdruck und lässt Dir mal die Teilergebnisse ausgeben. Und Du wirst sehen, wie einfach das gehen kann und wie kompliziert Du es ausgedrückt hast.

Auch hier trifft wieder meine Haupt-"Kritik" zu: Du denkst zu wenig über Code nach!

Re: Programm Kontrolle

Verfasst: Montag 18. Juni 2012, 08:37
von BlackJack
@Nobuddy: Die erste Zeile wurde ja schon angesprochen. Und mindestens ein weiterer Funktionsaufruf ist überflüssig — ich vermute sogar zwei.

`pid_current` würde ich nicht mit 0 vorbelegen. Das ist letztendlich eine gültige Prozess-ID die hier aber verwendet wird um „keine Prozess-ID gefunden” zu symbolisieren. Damit hat dieser Wert eine zweideutige Bedeutung. `None` würde sich hier als Wert anbieten.

Re: Programm Kontrolle

Verfasst: Montag 18. Juni 2012, 13:11
von Nobuddy
@Hyperion, boah ..., bin ich auf der Leitung gestanden, keine Ahnung warum das solange gedauert hat. :K
Dies reicht ja völlig:

Code: Alles auswählen

prog_short = programm[:15]
@BlackJack, das mit 'None' habe ich gemacht.
Nach etlichem Testen habe ich festgestellt, daß alleine mit:

Code: Alles auswählen

for prog in psutil.process_iter():
        if prog.name == prog_short and int(prog.pid) != int(pid_start):
            pid_current = prog.pid
            break
nicht einwandfrei funktioniert.
Ich benötige dies so,

Code: Alles auswählen

    for prog in psutil.process_iter():
        if prog.name != 'python' and prog.name == programm[:15] and int(prog.pid) != int(pid_start):
            pid_current = prog.pid
            print pid_current
            print '----'
            break
        elif programm in psutil.Process(int(prog.pid)).cmdline and int(prog.pid) != int(pid_start):
            pid_current = prog.pid
            print pid_current
            break
        else:
            pid_current = None
damit läuft dies bei mir fehlerfrei.

Manchmal wird bei:

Code: Alles auswählen

for prog in psutil.process_iter():
    print prog.name
nur 'python' und manchmal 'lbestellorder.p' ausgegeben. Somit bekomme ich dann keinen Treffer, weil ja mein Programm 'lbestellorder.py' heißt.
Daher benötige ich noch dies:

Code: Alles auswählen

programm in psutil.Process(int(prog.pid)).cmdline
und erhalte somit die Ausgabe
['python', 'lbestellorder.py']
.
Warum variiert die Ausgabe von 'name' bei Ersterem?

Re: Programm Kontrolle

Verfasst: Montag 18. Juni 2012, 13:23
von BlackJack
Eigentlich hatte ich mich ja schon rausgehalten weil ich das Gefühl hatte es bringt einfach nichts. Nach dem hier gebe ich dann doch endgültig auf: ``psutil.Process(int(prog.pid)).cmdline``… m(

Re: Programm Kontrolle

Verfasst: Montag 18. Juni 2012, 14:10
von Hyperion
Also bei mir sieht die Ausgabe doch ganz vernünftig aus:

Code: Alles auswählen

>>> for prog in psutil.process_iter():
...     print prog, prog.pid, type(prog.pid)
... 
psutil.Process(pid=1, name='init [5]') 1 <type 'int'>
psutil.Process(pid=2, name='kthreadd') 2 <type 'int'>
psutil.Process(pid=3, name='ksoftirqd/0') 3 <type 'int'>
psutil.Process(pid=6, name='migration/0') 6 <type 'int'>
psutil.Process(pid=7, name='watchdog/0') 7 <type 'int'>
psutil.Process(pid=8, name='cpuset') 8 <type 'int'>
psutil.Process(pid=9, name='khelper') 9 <type 'int'>
Wonach suchst Du denn jetzt genau? Ich dachte Du suchst nach der pid!?

Desweiteren schau Dir mal den Typen an, den `Process.pid` liefert! Das erklärt BlackJacks obigen Einwurf bezüglich der unnötigen Funktionsaufrufe...

Der von BlackJack monierte Aufruf ist natürlich der Hammer; hier mal in vier Teile gesplittet zur Herleitung der Sinnlosigkeit:

Code: Alles auswählen

>>> for prog in psutil.process_iter():
...     print prog
...     print prog.pid
...     print psutil.Process(prog.pid)
...     print psutil.Process(prog.pid).cmdline
... 
psutil.Process(pid=1, name='init [5]')
1
psutil.Process(pid=1, name='init [5]')
['init [5]']
psutil.Process(pid=2, name='kthreadd')
2
psutil.Process(pid=2, name='kthreadd')
[]
psutil.Process(pid=3, name='ksoftirqd/0')
3
psutil.Process(pid=3, name='ksoftirqd/0')
[]
Sollte Dir immer noch nicht klar sein, was Du da tust, so schau Dir doch mal das an:

Code: Alles auswählen

>>> psutil.Process(1)
<psutil.Process(pid=1, name='init [5]') at 139923431394256>
Hui... `psutil.Process(pid)` liefert mir also den Prozess zu einer existierenden PID... Du holst Dir die PID aber schon aus einem `Process`-Objekt, welches Du Dir durch den Schleifenkopf "erstellen" lässt. Indem Du also die PID aus einem bestehenden `Process`-Objekt holst und damit ein neues `Process`-Objekt erzeugst, welches *denselben* Prozess repräsentiert, drückst Du folgendes einfach nur in kompliziert aus:

Code: Alles auswählen

prog.cmdline
Man erkennt doch leicht, dass `print prog` und `print psutil.Process(prog.pid)` identisch sind...

... :roll:

Ich habe immerhin schon mal das unnütze `int(...)` weggelassen, was den Ausdruck noch komplizierter macht.

Ich habe mir nicht die komplette "Logik" in den `if`s angeguckt, denke aber mal, dass Du nur stumpf rätst und nicht wirklich sinnvoll Ausdrücke entwickelst.

Hast Du das eigentlich mal in einer Shell ausprobiert? Ich vermute mal, dass Du davon immer noch viel zu selten Gebrauch machst! Wie Du siehst habe ich das alles in einer Shell entwickelt und bin ohne alles übrige an Code auf den Sinn / Unsinn gekommen. Wenn Du Dinge immer nur im "großen" Programm ausprobierst, kommst Du echt nicht zu Potte und verrennst Dich zu sehr - wie man ja mal wieder gesehen hat!

Re: Programm Kontrolle

Verfasst: Montag 18. Juni 2012, 14:18
von Nobuddy
@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

Re: Programm Kontrolle

Verfasst: Montag 18. Juni 2012, 15:44
von Hyperion
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.

Re: Programm Kontrolle

Verfasst: Montag 18. Juni 2012, 18:58
von Nobuddy
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.

Re: Programm Kontrolle

Verfasst: Dienstag 19. Juni 2012, 05:53
von Hyperion
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...

Re: Programm Kontrolle

Verfasst: Dienstag 19. Juni 2012, 06:46
von 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

Re: Programm Kontrolle

Verfasst: Dienstag 19. Juni 2012, 08:03
von Nobuddy
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

Re: Programm Kontrolle

Verfasst: Dienstag 19. Juni 2012, 08:12
von 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.

Re: Programm Kontrolle

Verfasst: Dienstag 19. Juni 2012, 15:44
von Nobuddy
@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:

Re: Programm Kontrolle

Verfasst: Dienstag 19. Juni 2012, 16:37
von 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.

Re: Programm Kontrolle

Verfasst: Dienstag 19. Juni 2012, 17:34
von Nobuddy
@deets, ich wollte Dich keinesfalls irgendwie angreifen.
Willkuer oder Ignoranz sind schon harte Worte, hoffe daß ich Dich irgendwann vom Gegenteil überzeugen kann. :wink:

Re: Programm Kontrolle

Verfasst: Dienstag 19. Juni 2012, 18:27
von 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...

Re: Programm Kontrolle

Verfasst: Mittwoch 20. Juni 2012, 07:20
von Nobuddy
@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.

Re: Programm Kontrolle

Verfasst: Mittwoch 20. Juni 2012, 08:12
von Nobuddy
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:

Re: Programm Kontrolle

Verfasst: Mittwoch 20. Juni 2012, 13:38
von Nobuddy
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?

Re: Programm Kontrolle

Verfasst: Mittwoch 20. Juni 2012, 14:14
von 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.