2011-04-29 3 views
1

나는이 큐에 약간의 문제에 봉착 :함수를 호출 할 때이 스레드를 종료하는 가장 좋은 방법은 무엇입니까?

import Queue 
import threading 

class test(threading.Thread): 

    def __init__(self): 
     threading.Thread.__init__(self) 
     self.request_queue = Queue.Queue() 

    def addtoqueue(self, item): 
     self.request_queue.put(item) 

    def run(self): 
     while True: 
      item = self.request_queue.get(True) 
      print item 

이 간단한 클래스는 스레드 큐를 구현합니다. test::addtoqueue을 호출하면 항목이 대기열에 추가됩니다. 스레드는 항목이 대기열에 추가 될 때까지 기다리고 즉시 인쇄하고 다음 것을 기다립니다.

제 문제는 응용 프로그램 종료입니다. 스레드를 종료하는 가장 좋은 방법은 무엇입니까? 조건을 사용할 수는 있지만 어떻게 을 기다릴 수 있습니까?은 조건의 알림 또는 대기열의 새 항목 중 하나입니까?

답변

1

는) 그것을 죽일 :

poison = None # something you wouldn't normally put in the Queue 

class test(threading.Thread): 

    def __init__(self): 
     threading.Thread.__init__(self) 
     self.request_queue = Queue.Queue() 

    def kill(self): 
     self.addtoqueue(poison) 

    def addtoqueue(self, item): 
     self.request_queue.put(item) 

    def run(self): 
     while True: 
      item = self.request_queue.get(True) 
      if item is poison: 
       # do stuff 
       return # end thread 
      print item 
1

while 루프의 조건을 변경하여 로컬 변수를 확인했습니다. 외부 프로세스가 스레드를 종료 할 수 있도록 kill 스위치를 추가하십시오. kill_me을 확장하여 객체와 해당 큐를 좋은 방식으로 처리해야합니다 (예 : 큐를 다음에 실행할 때 저장하려는 경우).

편집 또한 에 변수가 추가되어 은 기본 프로세스 스레드를 차단해야합니다. 이렇게하면 스레드가 주 흐름으로 되돌아 가기 전에 종료 할 수 있습니다.

내가 overcomplicated 일을 할 수 있습니다, 당신은 스레드에 약간의 독을 보낼 수 있습니다

class test(threading.Thread): 

    def __init__(self): 
     threading.Thread.__init__(self) 
     self.request_queue = Queue.Queue() 
     self.is_running = True 
     self.has_finished = False 

    def addtoqueue(self, item): 
     self.request_queue.put(item) 

    def kill_me(self): 
     self.is_running = False 
     while not self.has_finished: 
      pass 

    def run(self): 
     while self.is_running: 
      item = self.request_queue.get(True) 
      print item 
     self.has_finished = True 
+1

을 흠 ... 한 가지 문제를 그래도. 'self.request_queue.get' 블록을 막기 때문에'self.is_running'을 실제로 테스트하지 않는다면 실제로'False'로 설정됩니다. –

+0

@George Edited! – Oli

1

일을 가능하게 할 수있는 간단한 일을 -이에있는, 사건은 센티넬일지도 몰라. threading 자바의 쓰레드 라이브러리에 의해 영감을했다 비록, 파이썬에서 일을 자바와 같은 수행과 threading.Thread에서 상속 것이 아니라, 가장 간단한 것은 threading.Thread()에 함수와 인수를 전달합니다 :

DONE = object() # Sentinel 

def run(queue): 
    while True: 
     item = queue.get() 
     queue.task_done() 
     if item is DONE: 
      break 
     print item 

request_queue = Queue.Queue() 
some_thread = Thread(target=run, args=(request_queue,)) 

some_thread.start() 

request_queue.put('hey') 
request_queue.put('joe') 
request_queue.put(DONE) 
관련 문제