代码之家  ›  专栏  ›  技术社区  ›  chhantyal

为什么并发。与futures一起使用时,futures executor map抛出错误。所有期货交易完成后,as\U完成了吗?

  •  2
  • chhantyal  · 技术社区  · 7 年前

    我正在尝试同时发送HTTP请求。为此,我使用 concurrent.futures

    下面是简单的代码:

    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'
    

    这是一个很奇怪的错误。在这里 executor.map 似乎有问题。如果我用下面的行替换map,它将按预期工作。

    futures_ = [executor.submit(send_request, x) for x in data]
    

    我错过了什么?试图找出两者之间的区别,但似乎无法理解上述问题的原因。如有任何意见,我们将不胜感激。

    1 回复  |  直到 7 年前
        1
  •  9
  •   skovorodkin    7 年前

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

    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)