다음 스크립트로 Python 스레딩을 테스트하고 있습니다.
import threading
class FirstThread (threading.Thread):
def run (self):
while True:
print 'first'
class SecondThread (threading.Thread):
def run (self):
while True:
print 'second'
FirstThread().start()
SecondThread().start()
이것은 Kubuntu 11.10의 Python 2.7에서 실행됩니다. Ctrl+ C는 그것을 죽이지 않을 것입니다. 또한 시스템 신호 처리기를 추가하려고 시도했지만 도움이되지 않았습니다.
import signal
import sys
def signal_handler(signal, frame):
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
프로세스를 죽이기 위해 나는 프로그램을 Ctrl+로 백그라운드로 보낸 후 PID로 죽이고 Z있는데, 무시되지 않습니다. Ctrl+ C가 왜 그렇게 지속적으로 무시되고 있습니까? 어떻게 해결할 수 있습니까?
답변
Ctrl+ C는 주 스레드를 종료하지만 스레드가 데몬 모드가 아니기 때문에 계속 실행되고 프로세스가 계속 유지됩니다. 데몬으로 만들 수 있습니다.
f = FirstThread()
f.daemon = True
f.start()
s = SecondThread()
s.daemon = True
s.start()
그러나 또 다른 문제가 있습니다. 일단 메인 스레드가 스레드를 시작하면 다른 작업이 수행되지 않습니다. 그래서 그것은 종료되고 스레드는 즉시 파괴됩니다. 따라서 메인 스레드를 유지합시다.
import time
while True:
time.sleep(1)
이제 Ctrl+ 를 누를 때까지 ‘첫 번째’와 ‘두 번째’를 계속 인쇄 C합니다.
편집 : 주석가가 지적했듯이 데몬 스레드는 임시 파일과 같은 것을 정리할 기회를 얻지 못할 수 있습니다. 필요한 경우 KeyboardInterrupt
메인 스레드에서 를 잡아서 정리 및 종료를 조정하십시오. 그러나 많은 경우 데몬 스레드를 갑자기 죽게하는 것으로 충분할 것입니다.
답변
KeyboardInterrupt와 시그널은 프로세스 (즉, 메인 스레드)에서만 볼 수 있습니다 … Ctrl-c ie KeyboardInterrupt를 살펴보면 파이썬에서 스레드를 죽일 수 있습니다.
답변
스레드가 죽을 것으로 예상 할 때 스레드에서 join ()을 호출하는 것이 가장 좋습니다. 루프를 끝내기 위해 코드를 자유롭게 사용했습니다 (청소가 필요한 모든 것을 거기에 추가 할 수도 있습니다). 변수 die는 각 패스에서 진실을 확인하고 True이면 프로그램이 종료됩니다.
import threading
import time
class MyThread (threading.Thread):
die = False
def __init__(self, name):
threading.Thread.__init__(self)
self.name = name
def run (self):
while not self.die:
time.sleep(1)
print (self.name)
def join(self):
self.die = True
super().join()
if __name__ == '__main__':
f = MyThread('first')
f.start()
s = MyThread('second')
s.start()
try:
while True:
time.sleep(2)
except KeyboardInterrupt:
f.join()
s.join()
답변
@Thomas K의 답변의 개선 된 버전 :
- 이 요점
is_any_thread_alive()
에 따라 어시스턴트 기능을 정의하면 자동으로 종료 될 수 있습니다 .main()
예제 코드 :
import threading
def job1():
...
def job2():
...
def is_any_thread_alive(threads):
return True in [t.is_alive() for t in threads]
if __name__ == "__main__":
...
t1 = threading.Thread(target=job1,daemon=True)
t2 = threading.Thread(target=job2,daemon=True)
t1.start()
t2.start()
while is_any_thread_alive([t1,t2]):
time.sleep(0)