如何限制创建的Thread对象的数量?

时间:2017-05-19 13:43:29

标签: python multithreading

我希望在以下代码中限制同时运行的class_f个对象的数量。即限制同时工作的线程数。我怎样才能做到这一点 ?

#!/usr/bin/env python

import random
import time
from threading import Thread

list_num = [1,2,3,4,5,6,7,8,9,10]

class class_f(Thread):

    def  __init__(self,x):
        Thread.__init__(self)
        self.x = x

    def run(self):

        time.sleep(random.randint(0,1))
        res = self.x * self.x
        print str(res)+"\n"


def main():
    for num in list_num:
        c=class_f(num)
        c.start()

if __name__ == "__main__":
    main()

2 个答案:

答案 0 :(得分:1)

我建议使用有界信号量。 您可以像这样实现它:

maxThreads = 10
semaphore = threading.BoundedSemaphore(maxThreads)

然后在线程开始工作之前,在__init__调用sempahore.acquire()中。线程完成后,调用sempahore.release()。获取减少存储在信号量中的数字。如果您尝试获取值为零的信号量,它将等待信号量再次释放。请查看Fredrik Lundh撰写的Thread Synchronization Mechanisms in Python,以获得有关使用semaphores的更深入说明。

答案 1 :(得分:1)

你可以在multiprocessing.pool中使用很大程度上没有文档的ThreadPool类,因为与你自己编写(这听起来像你需要的)相比,它可以让你想做的事情变得简单。

以下是如何将其应用于您问题中的代码(我还修改了该代码以更符合PEP 8 - Style Guide for Python Code建议):

from multiprocessing.pool import ThreadPool
import random
from threading import Lock, Thread
import time

MAX_THREADS = 5
threads = []
list_num = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print_lock = Lock()  # Prevents overlapped printing from threads.

class ClassF(Thread):
    def  __init__(self, x):
        Thread.__init__(self)
        self.x = x

    def run(self):
        time.sleep(random.randint(0, 1))
        res = self.x * self.x
        with print_lock:
            print(str(res) + '\n')


def main():
    pool = ThreadPool(processes=MAX_THREADS)
    for num in list_num:
        pool.apply_async(ClassF(num).start)

    pool.close()  # No more tasks will be submitted.
    pool.join()  # Wait for all threads to exit.

if __name__ == "__main__":
    main()