V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
thinker3
V2EX  ›  Python

ThreadPoolExecutor as_completed 会不会阻塞主线程。我问了 chatgpt 和 kimi 。 chatgpt 一开始说不会阻塞,在我的追问下说会阻塞。 kimi 非常坚持,一直说不会阻塞,是我的理解有问题。

  •  
  •   thinker3 · 202 天前 · 2560 次点击
    这是一个创建于 202 天前的主题,其中的信息可能已经有所发展或是发生改变。
    12 条回复    2024-05-11 23:23:24 +08:00
    thinker3
        1
    thinker3  
    OP
       202 天前
    问的 chatgpt 3.5
    Maerd
        2
    Maerd  
       202 天前
    不会阻塞
    调用 future.result()时才会阻塞
    msg7086
        3
    msg7086  
       202 天前
    Gemini 回复得很清晰啊,调用本身不会阻塞,然后获取结果的时候如果还没跑完才会阻塞,还有迭代器迭代完以后还没跑完的也会阻塞。

    我用的 Prompt 是「 Python ThreadPoolExecutor as_completed 会不会阻塞主线程。如果不会阻塞,那什么时候会阻塞呢?」,你自己可以问问看。
    thinker3
        4
    thinker3  
    OP
       202 天前
    @Maerd 调用 future.result()时已经有结果了,不会阻塞
    thinker3
        5
    thinker3  
    OP
       202 天前
    @msg7086 gemini 坚持认为 as_completed 不会 阻塞主线程。它只会阻塞 生成器 本身。尽管在我的追问中,它犯了一个明显的错误。也许是我对阻塞的理解有误,换一个说法:as_completed 会阻止主线程继续执行循环外的代码,直到所有任务完成。
    thinker3
        6
    thinker3  
    OP
       202 天前
    我一直追问 gemini, 它也改了:“因此,我们可以得出结论:as_completed 会阻塞 主线程 直到 所有 Future 对象完成。”
    abersheeran
        7
    abersheeran  
       202 天前   ❤️ 1
    你要是 for future in concurrent.futures.as_completed 那就会等到所有 future 完成,如果只是 concurrent.futures.as_completed 那就继续下一行了。

    另外,future.result() 会阻塞当前线程直到 future 完成为止。
    xuelang
        8
    xuelang  
       202 天前
    这样提问好些:
    Python 中 ThreadPoolExecutor as_completed 会不会阻塞主线程?
    一步步思考并回答,然后写一个程序验证下。

    回答:
    在 Python 中,使用 concurrent.futures.ThreadPoolExecutor 的 as_completed 函数确实会阻塞主线程,但这取决于你如何使用它。as_completed 是一个生成器,它在等待任何提交到线程池的未来( future )任务完成时阻塞。当你遍历 as_completed 生成的结果时,如果结果尚未准备好,主线程将阻塞直到至少一个任务完成。

    现在,让我们编写一个简单的程序来验证这一点。程序将创建一个线程池,提交几个任务,然后使用 as_completed 来检查这些任务的完成情况,观察主线程的行为。

    ```python
    import concurrent.futures
    import time

    # 一个简单的任务函数,让线程休眠一段随机时间
    def sleep_for_seconds(seconds):
    print(f"开始任务,休眠 {seconds} 秒...")
    time.sleep(seconds)
    return f"休眠了 {seconds} 秒后完成"

    # 创建线程池
    with concurrent.futures.ThreadPoolExecutor() as executor:
    # 提交几个任务到线程池
    futures = [executor.submit(sleep_for_seconds, seconds) for seconds in [2, 3, 5]]

    # 等待任务完成并打印结果
    for future in concurrent.futures.as_completed(futures):
    print(future.result())
    ```

    在这个例子中,as_completed 将阻塞主线程,直到最先完成的任务返回结果。接着它会继续阻塞,直到下一个任务完成,依此类推。每完成一个任务,它就打印出来,这样你可以看到主线程在等待时的行为。

    这篇文章写的不错 https://mp.weixin.qq.com/s/3CXn0osZ9xx7U15MRcBXuA 梳理了常见的一些异步任务等待。
    msg7086
        9
    msg7086  
       202 天前   ❤️ 1
    我重新理了一下 AI 的说法,我觉得应该是这样的。
    as_completed 产生迭代器这个操作是非阻塞的。找迭代器索要值的时候才会阻塞。

    比如说伪代码:
    1. a = as_completed(...)
    2. b = a.get(0)

    1 是不阻塞的,2 是阻塞的。
    AsAsSaSa
        10
    AsAsSaSa  
       202 天前   ❤️ 1
    你们到底在尝试 AI 是否合理,还是 as_completed 是否阻塞……
    如果是第二个问题,不如把文档复制过去提问(人工智能 RAG✘ 人工+智能✔)

    简单地说是这样:
    fs_ac = as_complete(fs)
    fut1 = next(fs_ac) # 在这里阻塞
    result = fut1.result()
    AsAsSaSa
        11
    AsAsSaSa  
       202 天前   ❤️ 1
    看了一下,as_complete 文档的中文翻译错了……我去修一下
    keakon
        12
    keakon  
       202 天前   ❤️ 1
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2107 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 00:37 · PVG 08:37 · LAX 16:37 · JFK 19:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.