Python에서 스레드를 종료하는 방법: 1. stop 함수를 호출하고 Join 함수를 사용하여 스레드가 제대로 종료될 때까지 기다립니다. 2. Python 스레드에서 예외를 발생시킵니다. 3. "thread.join"을 사용하여 종료합니다. 스레드.
이 기사의 운영 환경: Windows 7 시스템, Python 버전 3.5, DELL G3 컴퓨터.
파이썬에서 스레드를 종료하려면 일반적인 방법은 설정/확인 --->플래그 또는 잠금이라는 것을 알고 있습니다.
이 방법이 좋은가요?
좋으면 안 돼요! 모든 프로그래밍 언어에서 스레드를 갑자기 종료하는 것은 어쨌든 좋은 디자인 패턴이 아니기 때문입니다.
동시에
다음과 같은 경우에는 더욱 악화됩니다.
간단히 말하면, 공통 리소스를 공유하는 대규모 스레드 그룹이 있습니다. 스레드 중 하나가 리소스를 차지하게 되면 강제로 떠나게 되는 결과가 발생합니다. 리소스가 잠겨 있어 아무도 얻을 수 없습니다. 불멸자를 키우는 소설의 줄거리와 좀 비슷하지 않나요?
스레딩이 시작만 되고 끝이 없는 이유를 아시나요?
스레드는 일반적으로 네트워크 연결, 시스템 리소스 해제, 스트리밍 파일 덤프에 사용됩니다. 이것들은 모두 IO와 관련이 있습니다. 갑자기 스레드를 닫았을 때
제대로 닫히지 않으면 어떻게 해야 할까요? 당신은 단지 자신을 위해 버그를 만들고 있습니까? 아? !
그래서 이런 일에서 가장 중요한 것은 스레드를 종료하는 것이 아니라 스레드를 정리하는 것입니다.
더 좋은 방법은 각 스레드에 종료 요청 플래그를 두고 스레드에서 특정 간격으로 이를 확인하여 떠날 시간인지 확인하는 것입니다!
import threading class StoppableThread(threading.Thread): """Thread class with a stop() method. The thread itself has to check regularly for the stopped() condition.""" def __init__(self): super(StoppableThread, self).__init__() self._stop_event = threading.Event() def stop(self): self._stop_event.set() def stopped(self): return self._stop_event.is_set()
이 코드 부분에 표시된 것처럼 스레드를 종료하려면 명시적으로 stop() 함수를 호출하고, 스레드가 적절하게 종료될 때까지 기다려야 하는 Join() 함수를 사용해야 합니다. 스레드는 정기적으로 중지 플래그를 확인해야 합니다.
그러나 실제로 스레드를 종료해야 하는 몇 가지 사용 시나리오가 있습니다. 예를 들어 외부 라이브러리를 캡슐화했지만 외부 라이브러리 가 를 오랫동안 호출하여 프로세스를 중단하려는 경우입니다.
[권장: python 비디오 튜토리얼]
다음 해결 방법은 Python 스레드에서 예외 발생을 허용하는 것입니다(물론 몇 가지 제한 사항이 있습니다).
def _async_raise(tid, exctype): '''Raises an exception in the threads with id tid''' if not inspect.isclass(exctype): raise TypeError("Only types can be raised (not instances)") 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, 0) raise SystemError("PyThreadState_SetAsyncExc failed") class ThreadWithExc(threading.Thread): '''A thread class that supports raising exception in the thread from another thread. ''' def _get_my_tid(self): """determines this (self's) thread id CAREFUL : this function is executed in the context of the caller thread, to get the identity of the thread represented by this instance. """ if not self.isAlive(): raise threading.ThreadError("the thread is not active") # do we have it cached? if hasattr(self, "_thread_id"): return self._thread_id # no, look for it in the _active dict for tid, tobj in threading._active.items(): if tobj is self: self._thread_id = tid return tid # TODO: in python 2.6, there's a simpler way to do : self.ident raise AssertionError("could not determine the thread's id") def raiseExc(self, exctype): """Raises the given exception type in the context of this thread. If the thread is busy in a system call (time.sleep(), socket.accept(), ...), the exception is simply ignored. If you are sure that your exception should terminate the thread, one way to ensure that it works is: t = ThreadWithExc( ... ) ... t.raiseExc( SomeException ) while t.isAlive(): time.sleep( 0.1 ) t.raiseExc( SomeException ) If the exception is to be caught by the thread, you need a way to check that your thread has caught it. CAREFUL : this function is executed in the context of the caller thread, to raise an excpetion in the context of the thread represented by this instance. """ _async_raise( self._get_my_tid(), exctype )
댓글에 설명된 대로 이것은 "만병통치약"이 아닙니다. 왜냐하면 스레드가 Python 인터프리터 외부에서 사용 중이면 터미널 예외가 포착되지 않기 때문입니다~
이 코드를 사용하는 합리적인 방법은 다음과 같습니다. 스레드 특정 예외를 포착하고 정리 작업을 수행합니다. 이렇게 하면 작업을 종료하고 적절하게 정리할 수 있습니다.
인터럽트 방식과 비슷한 작업을 수행하려면 thread.join 방식을 사용할 수 있습니다.
join的原理就是依次检验线程池中的线程是否结束,没有结束就阻塞直到线程结束,如果结束则跳转执行下一个线程的join函数。 先看看这个: 1. 阻塞主进程,专注于执行多线程中的程序。 2. 多线程多join的情况下,依次执行各线程的join方法,前头一个结束了才能执行后面一个。 3. 无参数,则等待到该线程结束,才开始执行下一个线程的join。 4. 参数timeout为线程的阻塞时间,如 timeout=2 就是罩着这个线程2s 以后,就不管他了,继续执行下面的代码。
기본 조인 방법은 매개 변수 없음, 차단 모드이며 다른 스레드를 실행하기 전에 하위 스레드만 실행됩니다.
1. 두 개의 스레드가 동시에 시작되고 조인 기능이 실행됩니다.
2.waiting1 스레드가 3초 동안 실행(대기)된 후 종료됩니다.
3.waiting2 스레드가 8초 동안 실행(대기)된 후 작업이 종료됩니다.
4. Join 함수(메인 프로세스로 복귀) 실행이 종료됩니다.
이것은 스레드 실행이 시작된 후 수행되는 기본 조인 방법입니다. 조인 후 메인 스레드는 메인 스레드로 돌아가기 전에 하위 스레드가 완료될 때까지 기다려야 합니다.
timeout 매개변수인 Join 매개변수를 2, 즉 Join(2)로 변경하면 다음과 같은 결과가 나옵니다.
두 개의 스레드가 동시에 시작되고, Join 함수는 다음과 같습니다. 실행됩니다.
wating1 스레드는 3초 동안 실행(대기)한 후 완료되었습니다.
조인 종료(2가 2개, 총 4가, 36-32=4, 맞음).
waiting2 스레드가 Join에서 지정한 대기 시간(4초) 내에 완료되지 않아 나중에 실행을 완료했습니다.
join(2)은: 서브 스레드에 2초의 시간을 주고, 각 2초가 끝나면 떠날 것이며 조금도 걱정하지 않을 것입니다!
위 내용은 파이썬에서 스레드를 종료하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!