Zuallererst verwenden wir beim Beenden eines Threads häufig eine Methode: Festlegen einer Bedingung in der Schleifenbedingung der Sub-Thread-Ausführung. Wenn wir den Sub-Thread verlassen müssen, legen Sie die Bedingung fest. Zu diesem Zeitpunkt wird der untergeordnete Thread aktiv beendet. Wenn jedoch der untergeordnete Thread blockiert ist, werden in der Schleife keine Bedingungen beurteilt und die Blockierungszeit ist ungewiss. Wir haben keine Hoffnung, den Thread wiederzuverwenden. Zu diesem Zeitpunkt sind die folgenden Methoden erforderlich:
Wenn Sie einen Thread als Daemon-Thread festlegen, bedeutet dies, dass Sie sagen, dass dieser Thread nicht wichtig ist. Wenn der Prozess beendet wird, ist dies nicht erforderlich warte, bis dieser Thread beendet ist.
Wenn Ihr Hauptthread beim Beenden nicht auf den Abschluss dieser untergeordneten Threads warten muss, legen Sie die Daemon-Attribute dieser Threads fest. Das heißt, bevor der Thread startet (thread.start()), rufen Sie die Funktion setDeamon() auf, um das Daemon-Flag des Threads zu setzen. (thread.setDaemon(True)) bedeutet, dass dieser Thread „nicht wichtig“ ist.
Wenn Sie mit dem Beenden warten möchten, bis der untergeordnete Thread abgeschlossen ist, dann unternehmen Sie nichts. , oder rufen Sie explizit thread.setDaemon(False) auf, um den Daemon-Wert auf false zu setzen. Der neue untergeordnete Thread erbt das Daemon-Flag des übergeordneten Threads. Das gesamte Python wird beendet, nachdem alle Nicht-Daemon-Threads beendet wurden, d. h. wenn im Prozess keine Nicht-Daemon-Threads vorhanden sind.
Das heißt, der untergeordnete Thread ist ein Nicht-Deamon-Thread und der Hauptthread wird nicht sofort beendet
import threading import time import gc import datetime def circle(): print("begin") try: while True: current_time = datetime.datetime.now() print(str(current_time) + ' circle.................') time.sleep(3) except Exception as e: print('error:',e) finally: print('end') if __name__ == "__main__": t = threading.Thread(target=circle) t.setDaemon(True) t.start() time.sleep(1) # stop_thread(t) # print('stoped threading Thread') current_time = datetime.datetime.now() print(str(current_time) + ' stoped after') gc.collect() while True: time.sleep(1) current_time = datetime.datetime.now() print(str(current_time) + ' end circle')
Wird er vom Hauptthread gesteuert?
Der Daemon-Thread muss den Haupt-Thread beenden, um den Unter-Thread-Exit abzuschließen. Das Folgende ist der Code und kapselt ihn dann in einer Ebene, um zu überprüfen, ob der Haupt-Thread beendet werden muss.
def Daemon_thread(): circle_thread= threading.Thread(target=circle) # circle_thread.daemon = True circle_thread.setDaemon(True) circle_thread.start() while running: print('running:',running) time.sleep(1) print('end..........') if __name__ == "__main__": t = threading.Thread(target=Daemon_thread) t.start() time.sleep(3) running = False print('stop running:',running) print('stoped 3') gc.collect() while True: time.sleep(3) print('stoped circle')
import ctypes import inspect import threading import time import gc import datetime def async_raise(tid, exctype): """raises the exception, performs cleanup if needed""" tid = ctypes.c_long(tid) if not inspect.isclass(exctype): exctype = type(exctype) res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype)) if res == 0: raise ValueError("invalid thread id") elif res != 1: # """if it returns a number greater than one, you're in trouble, # and you should call it again with exc=NULL to revert the effect""" ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None) raise SystemError("PyThreadState_SetAsyncExc failed") def stop_thread(thread): async_raise(thread.ident, SystemExit) def circle(): print("begin") try: while True: current_time = datetime.datetime.now() print(str(current_time) + ' circle.................') time.sleep(3) except Exception as e: print('error:',e) finally: print('end') if __name__ == "__main__": t = threading.Thread(target=circle) t.start() time.sleep(1) stop_thread(t) print('stoped threading Thread') current_time = datetime.datetime.now() print(str(current_time) + ' stoped after') gc.collect() while True: time.sleep(1) current_time = datetime.datetime.now() print(str(current_time) + ' end circle')
Dies kommt der pthread-Kill-Operation in Unix am nächsten. Ich habe einige Verwendungen im Internet gesehen, aber ich habe die Verwendung in dieser Bibliothek nicht gefunden Dies ist die Beschreibung in Offizielles Signalerklärungsdokument von Python. Ich habe gesehen, dass es sich um die neue Version 3.3 handelt. Ich verwende Python3.10 und es gibt kein pthread_kill. Es kann in nachfolgenden Versionen entfernt werden.
Dies ist ein Beispielcode, den ich online gesehen habe, aber er kann nicht ausgeführt werden. Wenn jemand weiß, wie man ihn verwendet, können Sie mitteilen.
from signal import pthread_kill, SIGTSTP from threading import Thread from itertools import count from time import sleep def target(): for num in count(): print(num) sleep(1) thread = Thread(target=target) thread.start() sleep(5) signal.pthread_kill(thread.ident, SIGTSTP)
import time import gc import datetime import multiprocessing def circle(): print("begin") try: while True: current_time = datetime.datetime.now() print(str(current_time) + ' circle.................') time.sleep(3) except Exception as e: print('error:',e) finally: print('end') if __name__ == "__main__": t = multiprocessing.Process(target=circle, args=()) t.start() # Terminate the process current_time = datetime.datetime.now() print(str(current_time) + ' stoped before') time.sleep(1) t.terminate() # sends a SIGTERM current_time = datetime.datetime.now() print(str(current_time) + ' stoped after') gc.collect() while True: time.sleep(3) current_time = datetime.datetime.now() print(str(current_time) + ' end circle')
由于asyncio已经成为python的标准库了无需pip安装即可使用,这意味着asyncio作为Python原生的协程实现方式会更加流行。本文仅会介绍asyncio模块的退出使用。
使用协程取消,有两个重要部分:第一,替换旧的休眠函数为多协程的休眠函数;第二取消使用cancel()函数。
其中cancel() 返回值为 True 表示 cancel 成功。
示例代码如下:创建一个coroutine,然后调用run_until_complete()来初始化并启动服务器来调用main函数,判断协程是否执行完成,因为设置的num协程是一个死循环,所以一直没有执行完,如果没有执行完直接使用 cancel()取消掉该协程,最后执行成功。
import asyncio import time async def num(n): try: i = 0 while True: print(f'i={i} Hello') i=i+1 # time.sleep(10) await asyncio.sleep(n*0.1) return n except asyncio.CancelledError: print(f"数字{n}被取消") raise async def main(): # tasks = [num(i) for i in range(10)] tasks = [num(10)] complete, pending = await asyncio.wait(tasks, timeout=0.5) for i in complete: print("当前数字",i.result()) if pending: print("取消未完成的任务") for p in pending: p.cancel() if __name__ == '__main__': loop = asyncio.get_event_loop() try: loop.run_until_complete(main()) finally: loop.close()
Das obige ist der detaillierte Inhalt vonMit welcher Methode können Threads, Coroutinen und Prozesse in Python zwangsweise geschlossen werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!