Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.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,我有一个简单的Python网络爬虫。它使用SQLite存储其输出,并保留队列。我想让爬虫程序多线程,这样它可以一次抓取几个页面。我想我应该创建一个线程,然后一次运行该类的几个实例,这样它们都可以并发运行。但问题是,我应该一次跑多少?我应该坚持两个吗?我能再高一点吗?多少线程的合理限制是多少?请记住,每个线程都会转到一个网页,下载html,在其中运行一些正则表达式搜索,将找到的信息存储在SQLite数据库中,然后从队列中弹出下一个url。创建多个并发进程通常更简单。只需使用子流程创建您认为需要并发

我有一个简单的Python网络爬虫。它使用SQLite存储其输出,并保留队列。我想让爬虫程序多线程,这样它可以一次抓取几个页面。我想我应该创建一个线程,然后一次运行该类的几个实例,这样它们都可以并发运行。但问题是,我应该一次跑多少?我应该坚持两个吗?我能再高一点吗?多少线程的合理限制是多少?请记住,每个线程都会转到一个网页,下载html,在其中运行一些正则表达式搜索,将找到的信息存储在SQLite数据库中,然后从队列中弹出下一个url。

创建多个并发进程通常更简单。只需使用子流程创建您认为需要并发运行的尽可能多的popen

没有“最佳”数字。通常,当您只运行一个爬虫程序时,您的PC会花费大量时间等待。多少钱?很难说

当您运行少量并发爬虫程序时,您将看到它们所花费的时间与一个爬虫程序所花费的时间大致相同。您的CPU在各种进程之间切换,用一个进程的等待时间填满另一个进程的等待时间

当你运行一个更大的数字时,你会发现总的运行时间更长了,因为现在要做的事情比你的CPU所能管理的还要多。所以整个过程需要更长的时间

您可以创建一个图表,显示流程的扩展方式。基于此,您可以平衡进程的数量和所需的运行时间

这样想吧

1个爬虫在1分钟内完成它的工作。连续完成100页可能需要100分钟。同时运行100个爬虫程序可能需要一个小时。假设25个爬虫在50分钟内完成任务


在运行各种组合并比较结果之前,您不知道什么是最佳的。

您可能会发现您的应用程序是带宽受限的,而不是CPU或I/O受限的

因此,添加任意数量的内容,直到性能开始下降

根据您的网络设置,您可能会遇到其他限制。就像在ADSL路由器后面一样,并发NAT会话的数量会受到限制,这可能会影响一次发出过多HTTP请求。如果你赚的太多,你的提供商可能会认为你感染了病毒或类似的东西

还有一个问题是,您正在爬网的服务器可以处理多少请求,以及您希望在其上施加多少负载

我曾经写过一个只使用一个线程的爬虫程序。我花了大约一天的时间来处理我想要的所有信息,大约每两秒钟处理一页。我本来可以做得更快,但我认为这对服务器来说不是什么负担


所以真的没有一个简单的答案。假设一个1-5兆位的连接,我想说你可以轻松地拥有20-30个线程,而不会出现任何问题。

你可以将这两个线程提高到更高的水平。高出多少完全取决于运行此操作的系统的硬件、网络操作后正在进行的处理量以及当时机器上正在运行的其他内容

因为它是用Python编写的(并且被称为“简单”),所以我假设您并不完全关心从这个东西中挤出每一盎司的性能。在这种情况下,我建议在普通工作条件下运行一些测试,看看它的性能如何。我猜大概5-10分是合理的,但那完全是瞎猜


因为您使用的是双核机器,所以我强烈建议您查看(在Python2.6中)。它将让您充分利用计算机上的多个处理器,这将大大提高性能。

在这种情况下,线程是不必要的。您的程序受I/O限制,而不是CPU限制。最好在套接字上使用select()完成联网部分。这减少了创建和维护线程的开销。我没有使用过,但听说它对异步网络有很好的支持。这将允许您指定要下载的URL,并为每个URL注册回调。下载每个页面后,将调用回调,并且可以处理该页面。为了允许下载多个站点,而不必等待每个站点被处理,可以使用队列创建第二个“工作”线程。回调将把站点的内容添加到队列中。“worker”线程将执行实际的处理

正如在一些答案中已经指出的,同时下载的最佳数量取决于您的带宽


我会使用一个或两个线程,一个用于实际爬网,另一个(带有队列)用于处理。

如果你已经有一种简单的方法来输入任意长的URL列表,我会使用一个线程,或者使用一个延迟信号量或一个任务协作器


你不太可能制作出比基于twisted的爬虫更快或更小的多线程爬虫程序。

克莱特斯的答案就是你想要的答案


一些人提出了一种使用异步I/O的替代解决方案,特别是Twisted。如果您决定走这条路,另一种解决方案是,它是libcurl的薄包装,libcurl是一种广泛使用的URL传输库。PyCurl的主页上有一个“”示例,介绍了如何用大约120行代码并行获取多个页面。

您应该记住的一点是,有些服务器可能会将来自同一IP地址的太多并发请求解释为DoS攻击,并中止连接或返回错误页面,否则请求就会成功


因此,最好将对同一服务器的并发请求数量限制在相对较低的数量(5个应该是安全的)。

您需要对特定设置进行基准测试。考虑到网络是一种I/O操作