如何仅创建三个线程或固定数量的线程,并将列表X分配给它们

时间:2019-01-02 17:45:03

标签: python multithreading networking

假设有一个从某处接收数据的方法。在这种方法中,我们应该创建三个线程或固定数量的线程。每个接收到的数据都将分配给一个线程。

换句话说,如果您将收到10个数据列表(请注意,数据项的数量不固定且未知),则第一个列表将分配给第一个线程,第二个列表将分配给第二个线程线程,第三个列表到第三个线程,第四个列表将重新开始,并分配给第一个线程或任何可用线程,就像这样。

所以我们知道的唯一数字就是它们将在该方法中运行的线程数。

请注意,这三个线程应同时运行。线程可用或完成其任务后,它将获取下一个数据项并对其进行处理。

这就是我现在正在做的,但是如果我有30个数据列表,那么将创建30个线程,这很糟糕。

threads = []
for ip in ip_list:
    for cmd in commands:
        th = threading.Thread(target=test_ssh_conn(ip,cmd), args=(ip,))  # args is a tuple with a single element
        th.start()
        threads.append(th)

for th in threads:
    th.join()

1 个答案:

答案 0 :(得分:0)

您可以创建固定数量的线程,并使用线程安全的全局工作队列来存储任务。有任务时,工作线程轮询其中一项并对其进行处理。一旦工作队列为空,线程就可以重新加入main。

由于Python的解释器为single-threaded,请考虑使用multiprocessing。该API是相同的,因此很容易根据需要在两者之间进行切换。

这是一个使用一些模拟数据和一个函数存根进行模拟的基本示例:

from multiprocessing import Process, Queue
from queue import Empty
from random import uniform
from time import sleep


def work():
    while 1:
        try:
            test_ssh_conn(*tasks.get(timeout=0.5))
        except Empty:
            break

    print("thread exiting")

def test_ssh_conn(ip, cmd):
    print("working on %s %d" % (ip, cmd))
    sleep(uniform(1.0, 2.0)) # pretend to do work
    print("done working on %s %d" % (ip, cmd))


if __name__ == '__main__':  
    thread_count = 3
    threads = []
    tasks = Queue()
    ip_list = ["172.16.0.0", "172.31.255.255", "192.168.0.0"]
    cmds = list(range(5))

    for ip in ip_list:
        for cmd in cmds:
            tasks.put((ip, cmd))

    for _ in range(thread_count):
        th = Process(target=work)
        threads.append(th)
        th.start()

    for th in threads:
        th.join()

Try it!