限制并发线程数

时间:2017-06-17 10:26:57

标签: python multithreading python-multithreading

确保此代码一次只运行8个线程的最简单方法是什么。我需要它继续运行和重用线程。如果一个线程完成,它应该立即在另一个线程中启动。

threads = []
for user in user_list:
    thread = threading.Thread(target=parse_func, args= self,user,thread_name,), name= thread_name)
    thread.start()
    threads.append(thread)
for t in threads:
    t.join()

3 个答案:

答案 0 :(得分:1)

您可能需要查看semaphores并按照以下方式使用它:

threading.BoundedSemaphore(maximumNumberOfThreads)

从文档中可以看出,信号量通常用于保护容量有限的资源,例如数据库服务器。

另一个例子如下,取自documentation: 在产生任何工作线程之前,主线程将初始化信号量:

maxconnections = 5
...
pool_sema = BoundedSemaphore(value=maxconnections)

一旦产生,工作线程在需要连接到服务器时调用信号量的获取和释放方法:

pool_sema.acquire()
conn = connectdb()
... use connection ...
conn.close()
pool_sema.release()

答案 1 :(得分:1)

您需要线程池

线程池的想法是,不是创建新线程,而是应用程序代码创建新的任务,然后将任务提交给线程池。该池包含一些线程(可能是一个可变数,可能是固定数,取决于它的实现方式)和阻塞队列。

客户端程序将任务放入阻塞队列,而每个池线程都处于循环中,从队列中获取任务并执行

一个简单的线程池可能有一组固定的线程,它可能永远运行。复杂的线程池可能具有启动或关闭线程以响应不断变化的需求和/或更改系统负载的方法。

我没有足够的Python经验来了解是否存在每个人都使用的标准线程池接口,或者推荐任何现有的线程池实现。

你总是可以自己写。具有八个固定线程的线程池永远不会运行。

答案 2 :(得分:1)

我最终产生了我需要的确切线程数,让我们说100:

for i in range(100):
    Thread(target=get_url).start()

由于我希望每个线程保持活动状态并继续检查处理队列,因此我在每个线程中使用了一个无限循环,以便100个线程继续运行。我无法使用线程池,因为它会在队列第一次耗尽时立即关闭 - 如果我在一小时后用更多的工作重新填充队列,那么线程池就已经关闭了所以我必须做一定要创建一个新的池等。此时,维护我自己的池变得更容易。

def get_url():
    while True:
        item = q_worker.get()
        #do work with item
        q_worker.task_done()