0

这是情况。我需要每秒向 Django 视图函数发送一个 ajax 请求,该视图函数将向第三方 API 发送一些异步请求,以通过 grequests 获取一些数据。在此视图函数返回后,这些数据将呈现为 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 的线程数量一直在增加,直到出现“无法启动新线程”错误。 在此处输入图像描述

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

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

4

1 回答 1

0

也许你desc_ip_list的时间太长了,因此假设有一百个 IP,你会产生 100 个请求,由 100 个线程发出!

请参阅此处的 grequests 代码

你应该做什么:

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

编辑:更多信息,来自gevent 文档页面

作为 Group 的子类的 Pool 类提供了一种限制并发的方法:如果池中的 greenlet 数量已经达到限制,则其 spawn 方法将阻塞,直到有空闲槽。

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

map()中,我们从 lineno 113-114 开始:

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

在 lineno 85 in 中send(),我们有:

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

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

于 2015-12-10T13:07:38.040 回答