线程和线程池之间的真正区别?

Real difference between thread and threadpool?

在这个例子中有什么真正的区别还是只是语法糖?

    threads = []
    for job in jobs:
        t = threading.Thread(target=job, args=[exchange])
        t.start()
        threads.append(t)
    for thread in threads:
        thread.join()

    with concurrent.futures.ThreadPoolExecutor(max_workers=len(jobs)) as executor:
        for job in jobs:
            executor.submit(job, exchange)

ThreadPool 的重点应该是重用线程,但在这个例子中,所有线程都在“with”语句后退出,我说的对吗? 如何实现复用?在没有 with 语句的情况下让 ThreadPool 的实例保持活动状态?

您可以根据需要在其他地方使线程池保持活动状态。但在这种特殊情况下,您可能希望像这样利用 .submit 的结果:

with concurrent.futures.ThreadPoolExecutor(max_workers=len(jobs)) as executor:
    futures = []

    for job in jobs:
        future = executor.submit(job, exchange)
        futures.append(future)

    for future in futures:
        future.result()

这与原始线程非常相似,除了线程被重用并且使用 future.result() 我们可以检索值(如果有的话)并捕获异常(您可能想要尝试 - 除了 future.result() 调用).

btw,我不会max_workers=len(jobs),这似乎违背了ThreadPool的观点。此外,我鼓励您改为查看 async api 。无论如何,线程在 Python 中的使用有限。

你问的就像问拥有一辆卡车和只在你需要的时候租一辆卡车之间是否有任何真正的区别。

线程就像卡车。线程池就像卡车租赁公司。任何时候创建线程池,都在间接创建线程——可能不止一个。

创建和销毁线程是一项代价高昂的操作。线程池在不断创建许多需要在不同线程中执行的小 任务 的程序中很有用。程序不是为每个任务创建和销毁一个新线程,而是将任务提交给线程池,线程池将任务分配给它的 工作线程之一。 工作线程可以长寿。它们不需要不断地创建和销毁,因为每个都可以执行任意数量的任务。

如果您的程序创建的“任务”需要 运行 几乎与整个程序本身一样长,那么为此创建原始线程可能更有意义。但是,如果您的程序创建了许多短期任务,那么线程池可能是更好的选择。