【问题标题】:Is there a Python library equivalent of the Java's FixedThreadPool?是否有与 Java 的 FixedThreadPool 等效的 Python 库?
【发布时间】:2013-02-05 03:13:42
【问题描述】:

Python 中是否有一个简单的 ThreadPool 库,它具有例如 pool.execute(function, args) 方法,当池已满时应该阻塞(直到其中一个线程空闲)?

我曾尝试使用多处理包中的 ThreadPool,但它的 pool.apply_async() 函数在池已满时不会阻塞。实际上,我根本不明白它的行为。

【问题讨论】:

    标签: java python multithreading threadpool


    【解决方案1】:

    这个ActiveState Code Recipes page 有一个基于Python queue 的实现来进行阻塞。在 execute 的位置使用 add_task

    ## {{{ http://code.activestate.com/recipes/577187/ (r9)
    from Queue import Queue
    from threading import Thread
    
    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()
    
    if __name__ == '__main__':
        from random import randrange
        delays = [randrange(1, 10) for i in range(100)]
    
        from time import sleep
        def wait_delay(d):
            print 'sleeping for (%d)sec' % d
            sleep(d)
    
        # 1) Init a Thread pool with the desired number of threads
        pool = ThreadPool(20)
    
        for i, d in enumerate(delays):
            # print the percentage of tasks placed in the queue
            print '%.2f%c' % ((float(i)/float(len(delays)))*100.0,'%')
    
            # 2) Add the task to the queue
            pool.add_task(wait_delay, d)
    
        # 3) Wait for completion
        pool.wait_completion()
    ## end of http://code.activestate.com/recipes/577187/ }}}
    

    【讨论】:

      【解决方案2】:

      我修改了@ckhan 的答案并添加了回调功能。

      #Custom ThreadPool implementation from http://code.activestate.com/recipes/577187/
      # Usage:
      #       def worker_method(data):
      #           ''' do processing '''
      #           return data
      #           
      #       def on_complete_callback(data, isfailed):
      #           print ('on complete %s' % data)
      #           
      #       pool = ThreadPool(5)
      #       for data in range(1,10)
      #           pool.add_task(worker_method, on_complete_callback, data)    
      #       pool.wait_completion()
      
      from Queue import Queue
      from threading import Thread
      import thread
      
      class Worker(Thread):
          """Thread executing tasks from a given tasks queue"""
          def __init__(self, tasks, thread_id):
              Thread.__init__(self)
              self.tasks = tasks
              self.daemon = True
              self.start()
              self.thread_id = thread_id
      
          def run(self):
              while True:
                  func, callback, args, kargs = self.tasks.get()
                  try:
                      data = func(*args, **kargs)
                      callback(data, False)
                  except Exception, e:                
                      callback(e, True)
                  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 i in range(num_threads): Worker(self.tasks, i)
      
          def add_task(self, func, callback, *args, **kargs):
              """Add a task to the queue"""
              self.tasks.put((func, callback, args, kargs))
      
          def wait_completion(self):
              """Wait for completion of all the tasks in the queue"""
              self.tasks.join()
      

      【讨论】:

        【解决方案3】:
        from multiprocessing.pool import ThreadPool
        

        【讨论】:

        • ThreadPool 不支持池已满时的阻塞行为...正如 Ognhej 在他的问题中也提到的...
        猜你喜欢
        • 2013-06-07
        • 2010-12-19
        • 1970-01-01
        • 1970-01-01
        • 2011-04-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多