繁体   English   中英

在Python中使用多个线程

[英]using multiple threads in Python

我正在尝试解决一个问题,我有很多(大约一万个)URL,需要从所有这些网站下载内容。 我一直这样做是为了“链接中的链接:”循环到现在为止,但现在花费的时间太长了。 我认为是时候实现多线程或多处理方法了。 我的问题是,最好的方法是什么?

我知道全局解释器锁,但由于我的问题是网络限制,而不是CPU限制,我认为这不会是一个问题。 我需要将数据从每个线程/进程传回主线程/进程。 我不需要帮助实现任何方法( 当任何线程完成任务时终止多个线程 ),我需要建议采取哪种方法。 我目前的做法:

data_list = get_data(...)
output = []
for datum in data:
    output.append(get_URL_data(datum))
return output

没有其他共享状态。

我认为最好的方法是拥有一个包含所有数据的队列,并从输入队列中弹出几个工作线程,获取URL数据,然后推送到输出队列。

我对吗? 有什么我想念的吗? 这是我第一次用任何语言实现多线程代码,我知道这通常是一个难题。

对于您的特定任务,我建议使用多处理工作池 您只需定义一个池并告诉它您要使用多少个进程(默认情况下每个处理器核心一个)以及您希望在每个工作单元上运行的函数。 然后,您准备好每个工作单元 (在您的情况下,这将是一个URL列表)并将其提供给工作池。

您的输出将是原始数组中每个工作项的工作函数的返回值列表。 所有酷炫的多处理优点都将在后台进行。 当然还有其他与工作人员合作的方式,但这是我最喜欢的方式。

快乐多处理!

像这样执行IO绑定任务的最快和最有效的方法是异步事件循环。 libcurl可以做到这一点,并且有一个名为pycurl的Python包装器。 使用它的“多”界面,您可以执行高性能的客户端活动。 我已经完成了1000多次同步提取。

但是,API非常低级且难以使用。 有一个简化包装在这里 ,你可以作为一个例子使用。

我在您的用例中可以想到的最佳方法是使用线程池并维护工作队列。 线程池中的线程从工作队列中获得工作,完成工作然后再做一些工作。 这样,您就可以精确控制处理URL的线程数。

因此,创建一个WorkQueue,在您的情况下基本上是一个包含需要下载的URL的列表。

创建一个线程池,它创建您指定的线程数,从WorkQueue获取工作并将其分配给线程。 每次线程完成并返回时,检查工作队列是否有更多工作,并相应地再次为该线程分配工作。 您可能还想放置一个钩子,以便每次将工作添加到工作队列时,您的线程会将其分配给一个空闲线程(如果可用)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM