MultiProcessing多文件下载时进度条重复打印问题求助
问题解决:多进程下载时进度条重复打印的修复
问题原因
每个子进程独立创建并渲染alive_bar,多个进程同时向终端输出刷新指令,终端无法处理多个进度条的并行更新,导致进度条重复打印、显示混乱。
解决方案
让主进程统一管理进度显示,子进程仅负责下载任务,并通过进程间队列(multiprocessing.Queue)向主进程上报下载进度,由主进程单独更新进度条。
修改后的完整代码
from multiprocessing import Process, Queue from alive_progress import alive_bar import requests import time import os def download(url, queue): curr_dir = os.getcwd() # 获取文件真实地址和大小 try: x = requests.head(url, allow_redirects=True) file_size = int(x.headers['content-length']) // 1024 # 转为KB chunk_size = 1024 except Exception as e: print(f"获取文件信息失败: {e}") queue.put(('error', url)) return file_name = f"{curr_dir}\\{int(time.time())}.mp4" response = requests.get(url, stream=True) downloaded = 0 with open(file_name, 'wb') as f: for chunk in response.iter_content(chunk_size=chunk_size): if chunk: f.write(chunk) downloaded += 1 queue.put(('progress', 1)) # 每下载1KB发送一次进度 queue.put(('done', url)) if __name__ == '__main__': # 示例下载链接(替换为你的实际链接) links = [ "https://example.com/file1.mp4", "https://example.com/file2.mp4" ] num_processes = 2 processes = [] progress_queue = Queue() # 计算总文件大小(用于总进度条) total_size = 0 for url in links: try: x = requests.head(url, allow_redirects=True) total_size += int(x.headers['content-length']) // 1024 except: print(f"无法获取{url}的文件大小") # 启动子进程 for url in links[:num_processes]: p = Process(target=download, args=(url, progress_queue)) processes.append(p) p.start() # 主进程处理进度并更新进度条 completed = 0 with alive_bar(total_size, bar='classic2', spinner='classic') as bar: while completed < num_processes: msg_type, data = progress_queue.get() if msg_type == 'progress': bar(data) elif msg_type == 'done': completed += 1 print(f"\n{data} 下载完成!") elif msg_type == 'error': completed += 1 print(f"\n{data} 下载失败!") # 等待所有进程结束 for p in processes: p.join()
关键修改点
- 使用
multiprocessing.Queue实现主进程和子进程的进度通信,避免子进程直接输出到终端 - 主进程单独创建并控制
alive_bar,所有进度更新由主进程统一处理 - 修复原代码中
for i in num_processess的语法错误(改为遍历链接列表) - 增加异常处理,避免单个文件下载失败导致整个程序崩溃
内容的提问来源于stack exchange,提问作者Syed Abdullah
相关产品推荐
相关产品推荐

