IT TIP

Python의 스레드 내에서 호출 될 때 sys.exit ()가 종료되지 않는 이유는 무엇입니까?

itqueen 2020. 10. 14. 21:30
반응형

Python의 스레드 내에서 호출 될 때 sys.exit ()가 종료되지 않는 이유는 무엇입니까?


이것은 어리석은 질문이 될 수 있지만 Python에 대한 내 가정 중 일부를 테스트하고 있으며 다음 코드 조각이 스레드에서 호출 될 때 종료되지 않고 주 스레드에서 호출 될 때 종료되는 이유에 대해 혼란 스럽습니다.

import sys, time
from threading import Thread

def testexit():
    time.sleep(5)
    sys.exit()
    print "post thread exit"

t = Thread(target = testexit)
t.start()
t.join()
print "pre main exit, post thread exit"
sys.exit()
print "post main exit"

sys.exit ()에 대한 문서에는 호출이 Python에서 종료되어야한다고 명시되어 있습니다. 이 프로그램의 출력에서 ​​"post thread exit"가 인쇄되지 않는다는 것을 알 수 있습니다. 그러나 주 스레드는 스레드 호출이 종료 된 후에도 계속 진행됩니다.

인터프리터의 개별 인스턴스가 각 스레드에 대해 생성되고 exit ()에 대한 호출이 해당 개별 인스턴스를 종료합니까? 그렇다면 스레딩 구현은 공유 리소스에 대한 액세스를 어떻게 관리합니까? 스레드에서 프로그램을 종료하려면 어떻게해야합니까 (실제로 원하는 것은 아니지만 이해하도록 함)?


sys.exit ()는 thread.exit ()와 마찬가지로 SystemExit 예외를 발생시킵니다. 따라서 sys.exit ()가 해당 스레드 내에서 예외를 발생 시키면 thread.exit ()를 호출하는 것과 동일한 효과가 있으므로 스레드 만 종료됩니다.


스레드에서 프로그램을 종료하려면 어떻게해야합니까?

Deestan이 설명한 메서드 외에는 호출 할 수 있습니다 os._exit(밑줄에주의). 그것을 사용하기 전에 (전화 또는 이와 유사한) 정리 없다는 것을 이해했는지 확인하십시오 __del__.


스레드에서 프로그램을 종료하려면 어떻게해야합니까 (실제로 원하는 것은 아니지만 이해하도록 함)?

적어도 Linux에서는 다음과 같이 할 수 있습니다.

os.kill(os.getpid(), signal.SIGINT)

이것은 KeyboardInterrupt로 처리 될 수있는 메인 스레드에 SIGINT를 보냅니다.

BTW : Windows에서는 SIGTERM 시그널 만 보낼 수 있는데, 이는 파이썬에서 잡을 수 없습니다. (Helmut이 제안한대로 os._exit를 호출하는 것을 선호합니다)


"pre main exit, post thread exit"가 인쇄된다는 사실이 당신을 괴롭히는가?

sys.exit( System.exit자바의 경우) 아날로그가 VM / 프로세스 / 인터프리터를 즉시 중지시키는 다른 언어 (예 : Java)와 달리 Python sys.exit은 예외를 발생시킵니다. 특히 SystemExit 예외입니다.

다음은 sys.exit(단지 print sys.exit.__doc__)에 대한 문서입니다 .

SystemExit (status)를 올려 인터프리터를 종료합니다.
상태가 생략되거나 없음 인 경우 기본값은 0 (즉, 성공)입니다.
상태가 숫자이면 시스템 종료 상태로 사용됩니다.
다른 종류의 개체 인 경우 인쇄되고 시스템
종료 상태는 하나 (즉, 실패)가됩니다.

다음과 같은 몇 가지 결과가 있습니다.

  • 스레드에서 전체 프로세스가 아닌 현재 스레드를 종료합니다 (스택의 맨 위에 있다고 가정합니다 ...).
  • 객체 소멸자 ( __del__)는 해당 객체를 참조하는 스택 프레임이 풀릴 때 잠재적으로 호출됩니다.
  • 스택이 풀리면 마지막으로 블록이 실행됩니다.
  • SystemExit예외를 잡을 수 있습니다

마지막은 아마도 가장 놀라운 것일 수 있으며, except파이썬 코드에 정규화되지 않은 이 거의 없어야하는 또 다른 이유 입니다.


스레드에서 프로그램을 종료하려면 어떻게해야합니까 (실제로 원하는 것은 아니지만 이해하도록 함)?

내가 선호하는 방법은 Erlang-ish 메시지 전달입니다. 약간 단순화하여 다음과 같이합니다.

import sys, time
import threading
import Queue # thread-safe

class CleanExit:
  pass

ipq = Queue.Queue()

def testexit(ipq):
  time.sleep(5)
  ipq.put(CleanExit)
  return

threading.Thread(target=testexit, args=(ipq,)).start()
while True:
  print "Working..."
  time.sleep(1)
  try:
    if ipq.get_nowait() == CleanExit:
      sys.exit()
  except Queue.Empty:
    pass

참고 URL : https://stackoverflow.com/questions/905189/why-does-sys-exit-not-exit-when-called-inside-a-thread-in-python

반응형