2013-09-04 3 views
4

여기 내 스레딩 설정입니다. 내 컴퓨터에서 스레드의 최대 수는 2047 내 모듈에서 다른 클래스에서파이썬 스레드가 가비지 수집되지 않습니다.

class Worker(Thread): 
    """Thread executing tasks from a given tasks queue""" 
    def __init__(self, tasks): 
     Thread.__init__(self) 
     self.tasks = tasks 
     self.daemon = True 
     self.start() 

    def run(self): 
     while True: 
      func, args, kargs = self.tasks.get() 
      try: 
       func(*args, **kargs) 
      except Exception, e: 
       print e 
      self.tasks.task_done() 

class ThreadPool: 
    """Pool of threads consuming tasks from a queue""" 
    def __init__(self, num_threads): 
     self.tasks = Queue(num_threads) 
     for _ in range(num_threads): 
      Worker(self.tasks) 

    def add_task(self, func, *args, **kargs): 
     """Add a task to the queue""" 
     self.tasks.put((func, args, kargs)) 

    def wait_completion(self): 
     """Wait for completion of all the tasks in the queue""" 
     self.tasks.join() 

, 내가 스레드의 새로운 풀을 생성 에 위에서 ThreadPool이 클래스를 호출합니다. 그런 다음 작업을 수행합니다. 다음은 예입니다.

def upload_images(self): 
    '''batch uploads images to s3 via multi-threading''' 
    num_threads = min(500, len(pictures)) 
    pool = ThreadPool(num_threads) 

    for p in pictures: 
     pool.add_task(p.get_set_upload_img) 

    pool.wait_completion() 

문제점은 이러한 스레드가 가비지 수집되지 않는다는 것입니다.

파일 "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", 라인 495에 : 몇 가지를 실행 한 후에는

, 여기 내 오류입니다 _start_new_thread 시작 (자기 .__ 부트 스트랩을,()) thread.error 는 : 나는 2047

어떤 아이디어가의 스레드 한도에 도달 한 의미합니다 새 스레드

시작할 수 없습니다? 감사.

답변

4

작업자 스레드는 run에서 절대로 반환되지 않으므로 스레드가 종료되지 않습니다.

run 방법으로 다음과 같이 표시 될 수 있습니까?

def run(self): 
    while True: 
     try: 
      func, args, kargs = self.tasks.get() 
     except Queue.Empty: 
      break 

     try: 
      func(*args, **kargs) 
     except Exception, e: 
      print e 

     self.tasks.task_done() 
+0

코드를 잘못 사용하십시오. tasks.task_done()이 exit 라인을 따라 뭔가를하고 가비지가 쓰레드를 수집한다고 생각했습니다. –

+0

오, @ LucasOu-Yang'task_done()'이 예외 처리기 외부에 있어야합니다 (수정 해 드리겠습니다). 그래도'run' 메소드를 종료해야합니다. 작업 대기열은 처리 스레드에 대해 아무것도 모릅니다. –

1
def run(self): 
    while True: 
     func, args, kargs = self.tasks.get() 
     try: 
      func(*args, **kargs) 
     except Exception, e: 
      print e 
     self.tasks.task_done() 

이 무한 루프처럼 보이는, 그것은 이유가 될 수 있을까? 모든 스레드는 살아 있기 때문에 gc를 수집 할 수 없습니다.

관련 문제