nach externem Programmaufruf direkt weiter im Script

L I V E Stammtisch ab 20:30 Uhr im Chat
  • Hallo Leute,
    Ziel ist, pro GPIO-Taster jeweils sein zugeordnetes Bild aufzurufen (Taster1 -> Bild1, Taster2 ->Bild2 usw.).
    Mein Ansatz basiert auf dem Aufruf externer Programme über os.system("feh /Data/Bild1.jpg -F") bzw. subprocess.call(["feh", "/Data/Bild2.jpg", "-F"]).
    Im Code unten mal ein Versuch mit einem Taster (if not Taster then Bild1 else Bild2),

    Das Python Script wartet bis das externe Programm (hier feh) beendet wird ( z.bsp. mit <ESC>) und geht dann erst zur nächsten Programmzeile (Interpreter, logisch ;)).
    Ich möchte aber eine Struktur, welche nach dem Aufruf von feh sofort weiter fährt im Script.
    Wie löse ich das in Pythen?

    Danke für Eure Hilfe.

    Gruss superbike

  • nach externem Programmaufruf direkt weiter im Script? Schau mal ob du hier fündig wirst!

  • Das Python Script wartet bis das externe Programm (hier feh) beendet wird ( z.bsp. mit <ESC>) und geht dann erst zur nächsten Programmzeile

    Das ist normal - so ist das in Jeder Programmiersprache: Abarbeitung von oben nach unten.

    Ich möchte aber eine Struktur, welche nach dem Aufruf von feh sofort weiter fährt im Script.

    1. In dem du nicht darauf wartest dass das Script/Programm beendet wird

    2. oder indem du die Ausführung vom restlichen Script abspaltest (threading).

    Ersteres würde aber völlig reichen. Das erreichst du zB indem du den subprocess bzw den Befehl in den Hintergrund schickst, und das erreicht man wie auch bei normalen Konsolen Befehlen / bash Script mit einem " & " am Ende der Befehlszeile.


    PS: os.system ist veraltet und sollte nicht mehr verwendet werden.

  • Hallo meigrafd,


    ... und das erreicht man wie auch bei normalen Konsolen Befehlen / bash Script mit einem " & " am Ende der Befehlszeile.

    :blush: nur wie hänge ich das in den Übergabestring rein, so dass es keine Fehlermeldung gibt??
    subprocess.call(["feh", "/Data/Bild2.jpg", "-F"])
    ..............................................................abc
    a: "-F&"]) geht nicht weil kein feh-Parameter
    b: "-F", "&"]) Laufzeitfehler does not exist, skipping
    c: hinten angehängt mit/ohne "" gibt Syntaxfehler vor Laufzeit
    :blush: was mach ich falsch :blush:

  • > nur wie hänge ich das in den Übergabestring rein, so dass es keine Fehlermeldung gibt??
    Gar nicht, das ist Bloedsinn.

    In subprocess gibt es Popen und das macht genau das verlangte.

    Hier ist ein Beispiel:

    Code
    import subprocess
    import time
    
    
    p = subprocess.Popen( ["find","/","-name","*.py"] )
    time.sleep( 5 )
    p.terminate()

    Popen startet den Prozess und laeuft dann weiter. Wenn man ihn spaeter
    wieder loswerden will, schickt man ihm ein Signal oder ruft terminate auf.

  • Hallo Tell,
    passt, danke Dir für den Tipp.
    Kurz umgesetzt auf dem Weg zum Eingangs erwähnten Ziel:

    Gruss superbike

  • Hm ich dachte du wolltest das erreichen:

    Ziel ist, pro GPIO-Taster jeweils sein zugeordnetes Bild aufzurufen (Taster1 -> Bild1, Taster2 ->Bild2 usw.).

    Dein aktueller Code beachtet aber nur einen Taster - und so wie der Code aussieht würde es Probleme machen wenn der einfach für den 2.Taste copy&pasted werden würde :fies:

    Auch solltest du darüber nachdenken lieber Interrupts statt einer while Schleife zu nutzen - zumal es passieren könnte, das ein betätigter Taster wegen des sleep's nicht beachtet werden würde (ungünstiges timing)
    Achte jetzt mal auf deine CPU Auslastung, dann verstehst du meinen Hinweis
    (denn mit Interrupts wird kaum CPU Last erzeugt)
    Bezüglich Interrupt siehe hier:
    [Python] Hilfe bei Python script für Drehzahlmesser mit IR lichtschranke
    Interrupt löst ungewünscht aus
    Auf Flanken reagieren und mehrer Befehle ausführen
    https://www.forum-raspberrypi.de/Thread-raspbia…24687#pid124687

  • Auch wird ``GPIO.cleanup()`` in deinem Programm niemals aufgerufen. Egal was passiert.

    Begründung?

    Bezüglich CPU Auslastung würde ich mir keine Gedanken machen solange du das Programm mit ``time.sleep(x)`` blockierst.

    Von wegen "blockieren des Scripts" ist an sich imho Grund genug lieber Interrupts zu nutzen - unabhängig der erzeugten CPU-Last.

  • Begründung?

    Weil ab der ``while True`` Schleife Feierabend ist.


    Edit:
    Und ob ``signal.pause()`` eine wirkliche Alternative ist, kann ich auf meiner Windows Maschine nicht testen. Was aber jemand mal testen könnte - sofern er einen Taster bzw. ein Schalter hat - wäre folgendes:

    ggf anpassen. Es würde mich nämlich interessieren, ob ``signal.pause()`` mit sehr vielen innert kürzester Zeit Signalen fertig wird. Also wenn jemand ein Taster hat, dann bitte mal wie ein Verrückter an einem Street Fighter Spielhöllenautomat den Taster drücken...

  • Es würde mich nämlich interessieren, ob ``signal.pause()`` mit sehr vielen innert kürzester Zeit Signalen fertig wird. Also wenn jemand ein Taster hat, dann bitte mal wie ein Verrückter an einem Street Fighter Spielhöllenautomat den Taster drücken...

    ... signal.pause() funktioniert mit obigem Script am GPIO einwandfrei (einziger Einwand meine Fähigkeit des schnellen Tasterdrückens ;))

    meigrafd : ... ja um vom ersten Versuch nun zum Ziel zu kommen werde ich die Interrputs gem. deinen Links anwenden.
    Frage: gibts eigentlich auch einen time interrupt (alle xxx ms was ausführen, statt event triggered)?

    bootsmann : try / except verstanden, werde ich in Zukunft für solche Fälle nutzen


  • Frage: gibts eigentlich auch einen time interrupt (alle xxx ms was ausführen, statt event triggered)?

    Ja, ``time.sleep()`` ;)


    bootsmann : try / except verstanden, werde ich in Zukunft für solche Fälle nutzen

    Bedenke aber, dass du mit nur ``except`` also ohne Angabe von einer Exceptionklasse nicht weisst bzw sehen kannst, was nun der eigentliche Fehler ist.

  • Weil ab der ``while True`` Schleife Feierabend ist.

    Bei seinem aktuellen Code, ja. Aber normalerweise fügt man ja noch "try" und "except" ein um zB KeyboardInterrupt abzufangen und dann macht das schon Sinn zu haben ;)

    Was aber jemand mal testen könnte - sofern er einen Taster bzw. ein Schalter hat - wäre folgendes:

    [...]

    Es würde mich nämlich interessieren, ob ``signal.pause()`` mit sehr vielen innert kürzester Zeit Signalen fertig wird. Also wenn jemand ein Taster hat, dann bitte mal wie ein Verrückter an einem Street Fighter Spielhöllenautomat den Taster drücken...

    Solange man Interrupts verwendet spielt DAS keine Rolle. Die Reaktion kommt sofort da der Interrupt ja in einem eigenen Thread läuft.

    Spoiler anzeigen


    Frage: gibts eigentlich auch einen time interrupt (alle xxx ms was ausführen, statt event triggered)?


    Ja, ``time.sleep()`` ;)

    bootsmann: Das wäre aber imho nicht Sinn der Sache..

    Dazu gab es erst kürzlich einen Thread in dem einige Möglichkeit aufgeführt sind: Zeitversetzte Anweisung in der Scheife


    Die einfachste Lösung ist, den Command über ein screen im Hintergrund laufen lassen.

    Hm, was hat das mit dem Anliegen zu tun?

  • Na wenn du meinst, das wär jetzt ein Allheil-Rezept - dann viel Spass beim realisieren vernünftiger Anwendungen.. Klar kann es negative Auswirkungen haben wenn man planlos oder zu viele Threads nutzt. Aber wer schon mal größere Projekte programmiert hat kann auf Threads nicht wirklich verzichten, gerade in der heutigen Zeit.

    Nicht nur in diesem Fall würde der Verzicht auf Interrupts einen nicht zu verachtenden Mehraufwand bedeuten um es vernünftig (nahezu sofortige Reaktion ohne eine Eingabe zu verpassen) laufen zu lassen..

    Wäre gespannt wie Du das unter solchen Anforderungen ohne Threads realisieren würdest :huh:
    Aber wenn nicht, dann wäre solch ein Kommentar fehl am Platz....


  • bootsmann: Das wäre aber imho nicht Sinn der Sache..

    Warum?

    Und warum sollte man zusammengehörige Prozesse abkoppeln? Denn meist ist es der Fall, dass serielle Prozesse in Python langsamer laufen als Funktionen, welche nicht threadbasiert 'ausgelagert' werden. Zumindest in der Theorie ;)

    Es gibt für mich also keinen nachvollziehbaren Grund, hier die Funktion in einen Thread zu verlagern. Der einzige Grund, welcher mir auf die schnelle so einfällt einen Thread zu starten wäre zB bei einer GUI. Während ein Prozess bzw eine Funktion die milliardste Stelle von Pi berechnet, könnte die GUI einfrieren bzw während dieser Rechenzeit kann der User nichts weiter tun.

  • Ich glaube es macht hier (leider erneut) keinen Sinn weiter darüber zu diskutieren ... Du wirfst Argumente ein die nicht mal ansatzweise etwas mit diesem Thread zu tun haben - siehst das aber auch (leider erneut) nicht ein.

    Lese die Beiträge aufmerksamer und gehe auf das ein was gewollt sein könnte. Betrachte dabei auch den Kontext von Überschrift und vorherigem Anliegen. Dann sollten sich solche (leider erneut) Diskussionen wie nun hier, eigentlich erübrigen.


    ... im out ...

  • Hallo,
    Danke, mit dieser Diskussion habe ich wertvolle Tipps für meine geplanten Projekte erhalten, wo der Hauptprozess vor allem ein Benutzerinterface (Konsolenfenster, GUI, ext Programme) bedient.
    Daneben kommen total asynchron zum Hauptprozess laufend zyklische Aufgaben oder eben Ereignissgesteuerte dazu, welche die globalen Variablen füttern, welche vom Hauptprozess weiter bearbeitet / visualisiert weden.
    Da komme ich nicht um Threding herum; mit dem gebotenen Respekt mache ich mich auf ....
    Gruss superbike

Jetzt mitmachen!

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