Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中使用多线程_Python_Multithreading - Fatal编程技术网

在Python中使用多线程

在Python中使用多线程,python,multithreading,Python,Multithreading,我试图解决一个问题,我有很多(大约一万个)URL,需要从所有URL下载内容。到目前为止,我一直在一个“for link in links:”循环中这样做,但现在所花的时间太长了。我认为是时候实现多线程或多处理方法了。我的问题是,最好的方法是什么 我知道全局解释器锁,但由于我的问题是网络限制,而不是CPU限制,我认为这不会成为问题。我需要将数据从每个线程/进程传递回主线程/进程。我不需要帮助实施任何方法(包括这些),我需要关于采取哪种方法的建议。我目前的做法是: data_list = get_d

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

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

data_list = get_data(...)
output = []
for datum in data:
    output.append(get_URL_data(datum))
return output
没有其他共享状态

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


我说得对吗?我有什么遗漏吗?这是我第一次用任何语言实现多线程代码,我知道这通常是一个很难解决的问题。

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

您的输出将是原始数组中每个工作项的辅助函数返回值的列表。所有酷的多重处理都将发生在背景中。当然,也有其他方法可以使用worker pool,但这是我最喜欢的方法


快乐多处理

在您的用例中,我能想到的最佳方法是使用线程池并维护工作队列。线程池中的线程从工作队列中获取工作,完成该工作,然后再获取更多工作。通过这种方式,您可以很好地控制URL上的线程数量

因此,创建一个工作队列,在您的例子中,它基本上是一个包含需要下载的URL的列表


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

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


然而,API的级别很低,很难使用。有一个简化的包装器,您可以将其用作示例

+1。这绝对是最简单的解决方案。如果出于某种原因,您希望改用多线程解决方案,那么实现非常简单。请参见codereview.stackexchange.com。我认为多处理模块已经提供了一个(半隐藏)线程池类: