Python 为什么concurrent.futures executor map在与futures.as_completed一起使用时抛出错误(在所有futures完成后)?

Python 为什么concurrent.futures executor map在与futures.as_completed一起使用时抛出错误(在所有futures完成后)?,python,python-3.x,concurrency,python-multithreading,Python,Python 3.x,Concurrency,Python Multithreading,我正在尝试同时发送HTTP请求。为了做到这一点,我正在使用 下面是简单的代码: import requests from concurrent import futures data = range(10) def send_request(item): requests.get("https://httpbin.org/ip") print("Request {} complete.".format(item)) executor = futures.ThreadPo

我正在尝试同时发送HTTP请求。为了做到这一点,我正在使用

下面是简单的代码:

import requests
from concurrent import futures

data = range(10)


def send_request(item):
    requests.get("https://httpbin.org/ip")
    print("Request {} complete.".format(item))


executor = futures.ThreadPoolExecutor(max_workers=25)

futures_ = executor.map(send_request, data)

for f in futures.as_completed(futures_):
    f.result()
如果我运行它,我可以看到请求是异步发送的,这正是我想要做的。但是,当所有请求都完成时,我得到以下错误:

Request 0 complete.
Request 6 complete.
...
Request 7 complete.
Request 9 complete.
Request 3 complete.
Traceback (most recent call last):
  File "send_thread.py", line 18, in <module>
    for f in futures.as_completed(futures_):
  File "/usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/concurrent/futures/_base.py", line 219, in as_completed
    with _AcquireFutures(fs):
  File "/usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/concurrent/futures/_base.py", line 146, in __enter__
    future._condition.acquire()
AttributeError: 'NoneType' object has no attribute '_condition'
我错过了什么?试图找出两者之间的区别,但似乎无法理解是什么导致了上述问题。如果您有任何意见,我们将不胜感激。

不会返回您的未来列表,而是结果生成器,因此,请不要:

futures_ = executor.map(send_request, data)
for f in futures.as_completed(futures_):
    f.result()
您应该运行:

results = executor.map(send_request, data)
for r in results:
    print(r)

我明白了,非常感谢。这就引出了另一个问题:如果该生成器中的第一个请求比其他请求花费的时间更长(而
futures.as_完成了过程,正如它们完成的那样)?@chhantyal,您是正确的,它会阻止返回结果,以与传递相应的futures相同的顺序(模仿内置
map
函数)。如果您需要
futures.as_completed
behavior,
Executor.map
是不合适的。简而言之,
concurrent.futures
绝对不是并发发送HTTP请求的合适方式。你可能真的想要
aiohttp
lib.@skovorodkin#。再次谢谢你。@Sraw你是对的。然而,上面的请求只是一个简单的例子。我更希望在同步代码库中更快地进行IO调用,因此不能真正使用aiohttp。
results = executor.map(send_request, data)
for r in results:
    print(r)