Python 将TQM与concurrent.futures一起使用?

Python 将TQM与concurrent.futures一起使用?,python,concurrent.futures,tqdm,Python,Concurrent.futures,Tqdm,我有一个多线程函数,我想要一个状态栏来使用tqdm。有没有一种简单的方法可以使用ThreadPoolExecutor显示状态栏?让我困惑的是并行化部分 import concurrent.futures def f(x): return f**2 my_iter = range(1000000) def run(f,my_iter): with concurrent.futures.ThreadPoolExecutor() as executor: func

我有一个多线程函数,我想要一个状态栏来使用
tqdm
。有没有一种简单的方法可以使用
ThreadPoolExecutor
显示状态栏?让我困惑的是并行化部分

import concurrent.futures

def f(x):
    return f**2

my_iter = range(1000000)

def run(f,my_iter):
    with concurrent.futures.ThreadPoolExecutor() as executor:
        function = list(executor.map(f, my_iter))
    return results

run(f, my_iter) # wrap tqdr around this function?

您可以将
tqdm
环绕
executor
如下,以跟踪进度:

list(tqdm(executor.map(f,iter),total=len(iter))

以下是您的示例:

import time  
import concurrent.futures
from tqdm import tqdm

def f(x):
    time.sleep(0.001)  # to visualize the progress
    return x**2

def run(f, my_iter):
    with concurrent.futures.ThreadPoolExecutor() as executor:
        results = list(tqdm(executor.map(f, my_iter), total=len(my_iter)))
    return results

my_iter = range(100000)
run(f, my_iter)
结果是这样的:

16%|██▏           | 15707/100000 [00:00<00:02, 31312.54it/s]

16%|██▏           | 15707/100000[00:00最短的路,我想:

with ThreadPoolExecutor(max_workers=20) as executor:
    results = list(tqdm(executor.map(myfunc, range(len(my_array))), total=len(my_array)))

公认答案的问题是,
ThreadPoolExecutor.map
函数必须生成结果,而不是按照它们可用的顺序。因此,如果
myfunc
的第一次调用恰好是最后一次完成,则进度条将一次从0%变为100%,并且只有在所有f调用已完成。最好使用
ThreadPoolExecutor.submit
作为\u completed

import time
import concurrent.futures
from tqdm import tqdm

def f(x):
    time.sleep(0.001)  # to visualize the progress
    return x**2

def run(f, my_iter):
    l = len(my_iter)
    with tqdm(total=l) as pbar:
        # let's give it some more threads:
        with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
            futures = {executor.submit(f, arg): arg for arg in my_iter}
            results = {}
            for future in concurrent.futures.as_completed(futures):
                arg = futures[future]
                results[arg] = future.result()
                pbar.update(1)
    print(321, results[321])

my_iter = range(100000)
run(f, my_iter)
印刷品:

321 103041

这只是一般的想法。根据
my_iter
的类型,如果不先将
len
函数转换为列表,可能无法直接将其应用于
len
函数。主要的一点是在
完成时使用
submit
,谢谢!关键似乎是列表()关于tqdm,为什么会出现这种情况?@DreamFlasher:这种行为是因为tqdm是在执行时运行的。Executor.map本身只是一个生成器。这样,您不会立即获得输出!因此您必须等到完整的进度完成后,才能看到完整的结果!tqdm中的
total
参数很重要。没有它,我们就无法实现查看整体进度。谢谢!这确实很有帮助,但出于某种原因,进度条在一段时间后停止了?只想指出,经过一些小的修改(移动到
def main()
),这与的效果一样好,如果
f(x)可以更快
实际上执行计算,因为它不受全局解释器锁的影响。您可以从tqdm.contrib.concurrent import process\u map使用