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
'IT TIP' 카테고리의 다른 글
bindActionCreators는 언제 react / redux에서 사용됩니까? (0) | 2020.10.14 |
---|---|
Ruby에서 모듈의 인스턴스 변수를 초기화하려면 어떻게해야합니까? (0) | 2020.10.14 |
자식 클래스의 이름을 모르고 django에서 개체의 자식 클래스에 액세스하려면 어떻게해야합니까? (0) | 2020.10.14 |
gpg 명령 줄을 사용하여 암호가 올바른지 확인하는 방법 (0) | 2020.10.14 |
ggplot2를 사용하여 R의 각 막대에 대해 geom_bar에 레이블을 배치하는 방법 (0) | 2020.10.14 |