如何在python中启动一个线程池并在一个线程完成时停止?

Posted

技术标签:

【中文标题】如何在python中启动一个线程池并在一个线程完成时停止?【英文标题】:How to start a pool of threads and stop when one is finished in python? 【发布时间】:2022-01-19 21:06:28 【问题描述】:

我正在尝试编写一个同时发送多个请求并返回第一个响应的函数。我目前正在使用concurrent.futures.ThreadPoolExecutor 对象。我知道在中间停止请求很复杂,所以我认为我可以将其他线程保留在后台并尽早返回一个值。但是,该函数似乎在返回之前等待其他线程完成。我怎样才能防止这种情况?我的代码如下所示:

def req(urls):
    with concurrent.futures.ThreadPoolExecutor() as executor:
        futures = []
        for url in urls:
            futures.append(executor.submit(get_request, url))
        for future in concurrent.futures.as_completed(futures):
            if future.result():
                return future.result()  # Other threads should stop now
    return False  # No valid response was sent

【问题讨论】:

由于GIL,I/O 操作的多线程不是 Python 中的方式。通过asyncio 查看异步 I/O。见here。 【参考方案1】:

尝试关机https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor.shutdown

def req(urls):
    with concurrent.futures.ThreadPoolExecutor() as executor:
        futures = []
        for url in urls:
            futures.append(executor.submit(get_request, url))
        for future in concurrent.futures.as_completed(futures):
            if future.result():
                executor.shutdown(wait=False, cancel_futures=True)
                return future.result()  # Other threads should stop now
    return False  # No valid response was sent

【讨论】:

不幸的是,我的 python 似乎已经过时了,我无法使用cancel_futures 选项。 你也可以遍历所有的期货并在每个期货上调用.cancel() docs.python.org/3/library/… cancel 返回 False,因为线程仍处于挂起状态。

以上是关于如何在python中启动一个线程池并在一个线程完成时停止?的主要内容,如果未能解决你的问题,请参考以下文章

将鼠标光标更改为等待光标,然后启动工作线程并在线程完成时改回

如何在 Python 的单独线程中启动烧瓶 api 服务器

J2ME - 如何使线程返回一个值,并在该线程完成后,在其他操作中使用返回值?

启动多个线程并重新启动它们

python 用于启动qemu VM的好python脚本,等待15秒,并在启动过程中按活动排序cpu,以确保虚拟线程pi

Python - PyQt:重新启动已完成的线程