#python #concurrent.futures #tqdm
#питон #параллельные.фьючерсы #tqdm
Вопрос:
Я написал простую систему для параллельной обработки нескольких индикаторов выполнения tqdm, но по какой-то причине программа создает новую строку в конце каждого процесса, разрушая всю консоль.
Вот предварительный просмотр того, как это выглядит в действии.
class BaseHandler: def __init__(self, workers: int = 4): if (sys.platform == "win32"): loop = asyncio.ProactorEventLoop() asyncio.set_event_loop(loop) self.loop = asyncio.get_event_loop() self.semaphore = asyncio.Semaphore(workers) self.thread_executor = concurrent.futures.thread.ThreadPoolExecutor( max_workers = workers, ) def __call__(self, *args, **kwargs): return self._task_asynchronously(list(args)) def _task_asynchronously(self, values: list[int]): fs = [ self._pool_task(values[i], i) for i in range(len(values)) ] # Call all task asynchronously, and wait until all are finished return self.loop.run_until_complete( asyncio.gather(*fs) ) async def _pool_task(self, value: int, index: int = 0): # Run asynchronous task in a pool to make sure that all processes don't run at once. async with self.semaphore: return await self.loop.run_in_executor( self.thread_executor, self._heavy_task, value, index ) def _heavy_task(self, value: int, index: int = 0): with tqdm.tqdm(desc = str(index), position = index, leave = True, total = value) as pbar: for _ in range(value): pbar.update() pbar.close()
Я верю, что легко понять, как это работает:
BaseHandler(workers = 3)(2000000, 1000000, 3000000) # bunch of random entry
Обратите внимание, что я также пробовал базовый подход с
ThreadPoolExecutor.map
помощью , но он просто привел к тому же результату.
Я видел несколько постов, в которых говорилось leave=False
, что нужно там сидеть, но мне это не нравится.