我偶然发现了一个需要手动更新tqdm条的案例。具体来说,我试图跟踪一个由Fortran库启动的进程。在下面的代码中,我复制了行为,保留了面向案例的细节。当一个过程完成时,问题就出现了。具体地,当过程完成时,光标位置改变,并且因此条相对于它们的初始位置移动,从而留下先前的迭代。此外,它发生,如果一个酒吧试图更新自己,当另一个酒吧正在改变,它的位置是重新计算从那里留下一个混乱。我相信这种行为与没有锁定有关,或者是锁定条形图中更改的方法。我没有在网上找到任何东西,所以我在这里发布。应该可以用队列来解决这个问题,但我不希望传递tqdm对象,因为它们是不可拾取的。
from concurrent.futures import ThreadPoolExecutor, as_completed
import random
from tqdm.auto import tqdm
from time import sleep
from threading import Thread
def latest_time(dir:str):
return random.randint(0,100), 'a', False
def monitor_run(
dir:str,
name: str,
position: int,
max_iter: int,
refresh_progress: float=2,
) -> None:
sleep(1 + (position+1)/10)
with tqdm(
total = max_iter,
bar_format="{l_bar}{bar:30}{r_bar}",
desc=f"\t\t{name}: 0.0 Progress",
position= position,
ncols = 100,
leave = True,
ascii= True,
colour ='#00ff00',
) as pbar:
desc_prev: float = 0
while True:
sleep(refresh_progress)
time, desc, error = latest_time(dir)
if desc is None:
desc: float | None = desc_prev
else:
desc_prev = desc
pbar.desc = f"\t\t {name}: {desc} Progress"
if error:
pbar.write(f"Encountered Error at {desc}")
break
if time is None:
continue
pbar.n = int(time)
pbar.refresh(nolock=True)
if time>=max_iter:
pbar.close()
break
def serial_monitor(
dir:str,
position: int,
max_iter: int,
refresh_progress: float = 2,
)-> None:
monitor_run(dir,str(position), position ,max_iter, refresh_progress)
def serial_monitor_star(args)-> None:
serial_monitor(*args)
def parallel_monitor(
dirs: list[str],
max_iter: int,
refresh_progress: float =2,
) -> None:
args_list = [
[
dir, position+1, max_iter, refresh_progress
] for position, dir in enumerate(dirs)
]
# tqdm.write("\t\tStarting:")
# thread_map(
# serial_monitor_star, args_list, tqdm_class = tqdm ,max_workers = len(reynolds)
# )
# tqdm.write("\t\tCompleted")
with tqdm(total=2*len(dirs)):
with ThreadPoolExecutor(max_workers= len(dirs)) as ex:
futures = [
ex.submit(
serial_monitor_star,
args
) for args in args_list
]
for future in as_completed(futures):
result = future.result()
if __name__ =="__main__":
parallel_monitor(
['','','','','','',''],
100,
2
)
字符串
1条答案
按热度按时间33qvvth11#
也许您可以稍微调整一下代码(并使用
Queue
来更新条形图)。下面是一个示例,这可能是什么样子:工作线程向bar线程发送2个命令:
new
创建进度条,update
创建进度条。每个栏都有一个唯一的ID,工作人员使用此ID更新栏。字符串
这看起来像:
的数据