当我在无限循环中发送大量请求时,如何控制python线程?

时间:2015-12-10 08:04:25

标签: python multithreading grequests

情况如下。   我需要每秒向Django视图函数发送一个ajax请求,这个视图函数会向第三方API发送一些异步请求,以通过grequest获取一些数据。返回此视图函数后,这些数据将呈现为HTML。 这里显示代码

  desc_ip_list=['58.222.24.253', '58.222.17.38']
  reqs = [grequests.get('%s%s' % ('http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=', desc_ip))
        for desc_ip in desc_ip_list]
  response = grequests.map(reqs)

当我运行server django并发送这个ajax请求时,python的线程数量总是在增加,直到错误“无法启动新线程”发生。 enter image description here

error: can't start new thread
<Greenlet at 0x110473b90: <bound method AsyncRequest.send of <grequests.AsyncRequest object at 0x1103fd1d0>>(stream=False)> 
failed with error

如何控制线程数量?我不知道它,因为我是一个初学者pythoner。 非常感谢。

1 个答案:

答案 0 :(得分:0)

也许你的desc_ip_list太长了,因此,比方说,一百个IP,你将产生100个请求,由100个线程产生!

See here in the grequests code

你应该做什么:

您应该在size来电中指定map()个参数到合理的数字, 可能(2 * n + 1)其中n是CPU中的核心数, at max 。它将确保您不会同时处理desc_ip_list中的所有IP,从而产生尽可能多的线程。

编辑:更多信息,来自gevent doc page

  

Pool类是Group的一个子类,它提供了一种限制并发的方法:如果池中的greenlet数已经达到限制,它的spawn方法会阻塞,直到有一个空闲槽。

为什么我要提这个? 让我们从grequests中追溯它:

map()中,我们来自lineno 113-114:

pool = Pool(size) if size else None
jobs = [send(r, pool, stream=stream) for r in requests]

send()的lineno 85中,我们有:

return gevent.spawn(r.send, stream=stream)

这是将从send()执行的return语句, 因为它的参数pool将为None,因为在map()中,您没有指定size。现在回过头几行,阅读我从gevent文档中引用的内容。