Seite 1 von 1

Programm mit Thread mit einem KeyboardInterrupt beenden

Verfasst: Sonntag 21. Februar 2021, 20:19
von maksimilian
Hallo Ihr,
folgendes Testprogramm

Code: Alles auswählen

from time import sleep
import threading
from concurrent import futures
#
def proc1():
    while True:
        sleep(1)
#          
thread1 = futures.ThreadPoolExecutor(max_workers=1)
thread1.submit(proc1)
try:
    while True:
        sleep(1)
except KeyboardInterrupt:
    print("Thread beenden")
    thread1.shutdown()
    exit()
Ich benötige 3 x Strg+C um das Programm zu beenden. Wie kann ich erreichen, dass es mit nur einem Strg+C funktioniert.

Traceback:

Code: Alles auswählen

^CThread beenden
^CTraceback (most recent call last):
  File "test-exception.py", line 16, in <module>
    sleep(1)
KeyboardInterrupt

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test-exception.py", line 19, in <module>
    thread1.shutdown()
  File "/usr/lib/python3.7/concurrent/futures/thread.py", line 204, in shutdown
    t.join()
  File "/usr/lib/python3.7/threading.py", line 1032, in join
    self._wait_for_tstate_lock()
  File "/usr/lib/python3.7/threading.py", line 1048, in _wait_for_tstate_lock
    elif lock.acquire(block, timeout):
KeyboardInterrupt
^CError in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "/usr/lib/python3.7/concurrent/futures/thread.py", line 40, in _python_exit
    t.join()
  File "/usr/lib/python3.7/threading.py", line 1032, in join
    self._wait_for_tstate_lock()
  File "/usr/lib/python3.7/threading.py", line 1048, in _wait_for_tstate_lock
    elif lock.acquire(block, timeout):
KeyboardInterrupt

Re: Programm mit Thread mit einem KeyboardInterrupt beenden

Verfasst: Sonntag 21. Februar 2021, 20:36
von Sirius3
Warum verwendest Du einen ThreadPool für eine Endlosschleife?
Normalerweise benutzt man da einen normalen Thread mit daemon=True.

Re: Programm mit Thread mit einem KeyboardInterrupt beenden

Verfasst: Montag 22. Februar 2021, 07:12
von noisefloor
Hallo,

es gibt threading.Event, mit dem du einem einfache "Kommunikaiton" mit dem Thread machen kannst. Z.B. solange das Event nicht gesetzt ist läuft die Endlosschleife, wenn es gesetzt wird nicht mehr und Thread beendet sich.

Gruß, noisefloor

Re: Programm mit Thread mit einem KeyboardInterrupt beenden

Verfasst: Montag 22. Februar 2021, 11:21
von maksimilian
Sirius3 hat geschrieben: Sonntag 21. Februar 2021, 20:36 Warum verwendest Du einen ThreadPool für eine Endlosschleife?
Ganz einfach, weil ich es nicht besser weiß bzw. weil das in einer Literatur gefundenen Beispiel funktioniert. Ich implementiere gerade ein kleines Projekt, in welchem Interprozess-Kommunikation über eine Pipe in einem Thread läuft, welcher eintreffende Ereignisse in eine Queue schreibt, die in main abgearbeitet wird.
Sirius3 hat geschrieben: Sonntag 21. Februar 2021, 20:36 Normalerweise benutzt man da einen normalen Thread mit daemon=True.
Wie sieht da die Syntax aus ?

Re: Programm mit Thread mit einem KeyboardInterrupt beenden

Verfasst: Montag 22. Februar 2021, 11:38
von maksimilian
noisefloor hat geschrieben: Montag 22. Februar 2021, 07:12 Hallo,

es gibt threading.Event, mit dem du einem einfache "Kommunikaiton" mit dem Thread machen kannst. Z.B. solange das Event nicht gesetzt ist läuft die Endlosschleife, wenn es gesetzt wird nicht mehr und Thread beendet sich.

Gruß, noisefloor
Warum brauche ich ein threading.even ? Im Thread kann man doch eine globale Variable abfragen. Außerdem: welchen Unterschied macht es, einen Tread sich selbst beenden zu lassen oder das mit thread.shutdown() von außen zu tun ?

Grundsätzlich noch die Frage zu meinem Beispiel: Warum braucht es 3x Ctrl+C ? Was läuft da ab ?

Re: Programm mit Thread mit einem KeyboardInterrupt beenden

Verfasst: Montag 22. Februar 2021, 13:06
von noisefloor
Hallo,
Im Thread kann man doch eine globale Variable abfragen.
Weil man generell keine globalen Variablen beenden möchte.
Außerdem: welchen Unterschied macht es, einen Tread sich selbst beenden zu lassen oder das mit thread.shutdown() von außen zu tun ?
Zitat dazu aus der Python-Doku: "Note: Daemon threads are abruptly stopped at shutdown. Their resources (such as open files, database transactions, etc.) may not be released properly. If you want your threads to stop gracefully, make them non-daemonic and use a suitable signalling mechanism such as an Event."

Gruß, noisefloor

Re: Programm mit Thread mit einem KeyboardInterrupt beenden

Verfasst: Montag 22. Februar 2021, 20:29
von maksimilian
threading.Event kann den Thread nicht aus einem Pipe-read werfen.

Ich habe jetzt auf "normalen" Thread umgestellt und das funktioniert auch. Wieder was gelernt.

Re: Programm mit Thread mit einem KeyboardInterrupt beenden

Verfasst: Dienstag 23. Februar 2021, 10:17
von noisefloor
Hallo,
threading.Event kann den Thread nicht aus einem Pipe-read werfen.
threading.Event kann gar nichts, außer halt das Event setzen oder ein gesetztes Event löschen. _Was_ du daraus machst ist dein Sache, also wie dein Programm auf das gesetzte Event reagiert.

Gruß, noisefloor

Re: Programm mit Thread mit einem KeyboardInterrupt beenden

Verfasst: Donnerstag 25. Februar 2021, 19:58
von maksimilian
maksimilian hat geschrieben: Montag 22. Februar 2021, 20:29 threading.Event kann den Thread nicht aus einem Pipe-read werfen.
Aber ein Open in main() auf die Pipe.