2017-02-15 22 views
1

다음과 같이 Python 멀티 스레드 프로그램을 사용하고 있습니다. ctrl + c를 약 5 초 내에 누르면KeyboardInterrupt 예외가 발생합니다.Python에서 ctrl-c로 끝나는 파이썬 스레드

코드를 15 초 이상 실행하면 Ctrl + c에 응답하지 못했습니다. 15 초 후에 Ctrl + C를 누르면 작동하지 않습니다. KeyboardInterrupt 예외를 throw하지 않음입니다. 그 이유는 무엇일까요? 나는 이것을 리눅스에서 테스트했다.

threads = [t.join(1) for t in threads if t is not None and t.isAlive()] 

의 제 실행하여 변수 threads 번째 실행 후

[None, None, None, None, None, None, None, None, None, None] 

포함 후

#!/usr/bin/python 

import os, sys, threading, time 

class Worker(threading.Thread): 
    def __init__(self): 
    threading.Thread.__init__(self) 
    # A flag to notify the thread that it should finish up and exit 
    self.kill_received = False 

    def run(self): 
     while not self.kill_received: 
      self.do_something() 

    def do_something(self): 
     [i*i for i in range(10000)] 
     time.sleep(1) 

def main(args): 

    threads = [] 
    for i in range(10): 
     t = Worker() 
     threads.append(t) 
     t.start() 

    while len(threads) > 0: 
     try: 
      # Join all threads using a timeout so it doesn't block 
      # Filter out threads which have been joined or are None 
      threads = [t.join(1) for t in threads if t is not None and t.isAlive()] 
     except KeyboardInterrupt: 
      print "Ctrl-c received! Sending kill to threads..." 
      for t in threads: 
       t.kill_received = True 

if __name__ == '__main__': 
    main(sys.argv) 

답변

1

같은 변수 threads는 포함

[] 

이 시점에서 len(threads) > 0은 거짓이며 while 루프에서 벗어납니다. 여전히 10 개의 스레드가 활성화 되었기 때문에 스크립트가 계속 실행 중입니다. 그러나 KeyboardInterrupt를 잡으려고 try/except 블록에 있지 않으므로 Ctrl + C를 사용하여 중지 할 수 없습니다.

$ python thread_test.py 
thread 0 started 
thread 1 started 
thread 2 started 
thread 3 started 
thread 4 started 
thread 5 started 
thread 6 started 
thread 7 started 
thread 8 started 
thread 9 started 
Before joining 
After join() on threads: threads=[None, None, None, None, None, None, None, None, None, None] 
Before joining 
After join() on threads: threads=[] 
main() execution is now finished... 

는 사실, Ctrl + C 15 초 후에 작동을 중지하지 않지만, 이후 10 11초 :

#!/usr/bin/python 

import os, sys, threading, time 

class Worker(threading.Thread): 
    def __init__(self): 
    threading.Thread.__init__(self) 
    # A flag to notify the thread that it should finish up and exit 
    self.kill_received = False 

    def run(self): 
     while not self.kill_received: 
      self.do_something() 

    def do_something(self): 
     [i*i for i in range(10000)] 
     time.sleep(1) 

def main(args): 

    threads = [] 
    for i in range(10): 
     t = Worker() 
     threads.append(t) 
     t.start() 
     print('thread {} started'.format(i)) 

    while len(threads) > 0: 
     print('Before joining') 
     try: 
      # Join all threads using a timeout so it doesn't block 
      # Filter out threads which have been joined or are None 
      threads = [t.join(1) for t in threads if t is not None and t.isAlive()] 
      print('After join() on threads: threads={}'.format(threads)) 

     except KeyboardInterrupt: 
      print("Ctrl-c received! Sending kill to threads...") 
      for t in threads: 
       t.kill_received = True 
    print('main() execution is now finished...') 

if __name__ == '__main__': 
    main(sys.argv) 

그리고 결과를 : 스크립트는 내가 설명한 것을 볼 수 있습니다. 이것은 10 개의 스레드 (초 미만)를 생성 및 시작하고 각 스레드에서 join (1)을 실행하는 데 필요한 시간입니다 (약 10 초).

the doc에서

힌트 :

으로 가입() 항상 반환 없음, 당신이 가능한지 (호출하지합니다) 후 (가입) 타임 아웃이 발생 여부를 결정하기 - 스레드가 아직 살아 경우는 (가입) 통화 시간이 초과되었습니다.