You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python多进程程序如何统计每秒操作数?以批量图片下载任务为例

解决方案

以下两种实现方式性能损耗极低,完全适配数千张图片的批量下载场景:

方案1:实时统计每秒下载次数(可动态查看当前速度)

用multiprocessing.Value做进程安全的全局计数器,主进程单独开一个守护线程定时输出速度,方便你动态观察不同进程数下的速度变化:

import os
import requests
import time
from multiprocessing import Pool, Value
from threading import Thread

# 初始化进程共享计数器,'i'代表整数类型,初始值为0
complete_count = Value('i', 0)
start_time = None

# 子进程初始化函数,把共享计数器绑定到子进程全局变量
def init_counter(counter):
    global complete_count
    complete_count = counter

def download_image(image):
    save_dir = "[PATH TO SAVE IMAGES]"
    image_url = image['url']
    image_name = image['name']
    try:
        image_data = requests.get(image_url, timeout=10).content
        with open(os.path.join(save_dir, f"{image_name}.jpg"), 'wb') as f:
            f.write(image_data)
    finally:
        # 下载完成(不管成功失败)计数+1,自带锁保证计数安全
        with complete_count.get_lock():
            complete_count.value += 1

# 速度统计线程,每秒输出一次当前统计数据
def stat_speed(total_num):
    while True:
        elapsed = time.time() - start_time
        current_count = complete_count.value
        qps = current_count / elapsed if elapsed > 0 else 0
        # 可自定义输出格式,当前输出下载进度、平均QPS
        print(f"进度:{current_count}/{total_num} | 平均QPS:{qps:.2f} 张/秒", end='\r')
        if current_count >= total_num:
            break
        time.sleep(1)

if __name__ == "__main__":
    # 替换为你的图片列表
    images = [...]
    total = len(images)
    start_time = time.time()

    # 初始化进程池时传入计数器初始化方法和参数
    pool = Pool(8, initializer=init_counter, initargs=(complete_count,))
    
    # 启动速度统计线程
    stat_thread = Thread(target=stat_speed, args=(total,), daemon=True)
    stat_thread.start()

    # 执行下载任务
    pool.map(download_image, images)
    pool.close()
    pool.join()

    # 输出最终统计结果
    total_time = time.time() - start_time
    final_qps = total / total_time
    print(f"\n下载完成 | 总耗时:{total_time:.2f}s | 最终平均QPS:{final_qps:.2f} 张/秒")

小提示:如果需要只统计成功下载的QPS,把上述代码finally块里的计数逻辑,移动到write执行完成之后即可。

方案2:仅统计更精准的总平均QPS(不需要实时输出)

如果不需要实时看速度,只是不想把进程池初始化、收尾的时间算进平均,可以用Pool.imap_unordered迭代已完成的任务,从第一个任务完成时开始计时,统计结果比直接算Pool全生命周期的平均更准确:

import os
import requests
import time
from multiprocessing import Pool

def download_image(image):
    save_dir = "[PATH TO SAVE IMAGES]"
    image_url = image['url']
    image_name = image['name']
    image_data = requests.get(image_url, timeout=10).content
    with open(os.path.join(save_dir, f"{image_name}.jpg"), 'wb') as f:
        f.write(image_data)
    return True

if __name__ == "__main__":
    # 替换为你的图片列表
    images = [...]
    total = len(images)
    pool = Pool(8)
    
    complete = 0
    start_time = None
    # 迭代已完成的任务,第一个任务返回时才开始计时,排除进程启动耗时
    for res in pool.imap_unordered(download_image, images):
        if start_time is None:
            start_time = time.time()
        complete += 1

    pool.close()
    pool.join()

    total_time = time.time() - start_time
    qps = complete / total_time
    print(f"平均QPS:{qps:.2f} 张/秒")

内容的提问来源于stack exchange,提问作者MightyOwl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 02:27:04