情况如下。 我需要每秒向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。 非常感谢。
答案 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文档中引用的内容。