无限循环发送大量请求,如何控制python线程?

How can I control python thread when I send a lot requests in a limitless loop?

情况是这样的。 我需要每秒向 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)

当我运行服务器 django 并发送此 ajax 请求时,python 的线程数量一直在增加,直到发生错误 "can't start new thread"。 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。 非常感谢。

也许您的 desc_ip_list 太长了,假设有 100 个 IP,您将产生 100 个请求,由 100 个线程发出!

See here in the grequests code.

你应该做什么:

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

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

The Pool class, which is a subclass of Group, provides a way to limit concurrency: its spawn method blocks if the number of greenlets in the pool has already reached the limit, until there is a free slot.

我为什么要提这个? 我们从grequests追溯一下:

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

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

send() 的第 85 行中,我们有:

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

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