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

为什么Python中使用threading会导致I/O速度大幅下降?该如何解决?

Python多线程保存文件速度异常问题排查与解答

原始问题

我编写了一个函数,可将大型字典列表按每份100项的规则拆分保存到文件中。该逻辑在常规运行环境下完全正常,但我仅将其改为使用threading运行后,就出现了非常明显的速度下降。就我所知,单纯引入threading或multiprocessing不会导致I/O变慢,如果我遗漏了什么基础知识点请指出,否则还请告知如何解决运行过慢的问题?

相关代码

def savePlayerQueueToDisk(saveCopy):
        print("="*10)
        print("Application exit signal received. Caching loaded players...")
        import pickle
        i = 0
        for l in chunks(saveCopy, 100):
            with open(CACHED_PLAYERS_DIR / f"{str(i)}", 'wb') as filehandle:
                pickle.dump(saveCopy, filehandle)
            i += 1
            print(f"saved chunk {i}")
        import sys
        print("="*10)
        sys.exit()
def mainFunction():
    # Calls a main program, where on KeyboardException, it calls the savePlayerQueueToDisk function.
    t2 = threading.Thread(target=main, kwargs={'ignore_exceptions': False})
    t2.start()

排查过程

补充测试1

经过更多测试,我改用multiprocessing替代threading,仅给原来的线程任务开一个独立子进程,mainFunction保留在主线程运行,此时就没有出现速度下降的问题。

最终根因定位

后续经过进一步测试调试,我发现该问题实际上和multiprocessing、I/O bound都无关,是savePlayerQueueToDisk()函数第8行存在逻辑错误:原代码写的是pickle.dump(saveCopy, filehandle),实际应该是pickle.dump(l, filehandle)。每次运行函数时我都会把完整列表保存到100多个文件中,后续加载所有这些文件后又会把每份数据再复制100次存到100多个文件里,显然读写这些数据的负载会越来越高,最终失控。

解答

你遇到的速度下降本质和多线程、多进程的性能差异没有直接关系,核心触发原因就是你定位到的序列化逻辑错误:

  • 错误逻辑下,你每次循环都序列化并写入整个原始大列表,而非拆分后的100项小分片。假设你的列表有10000项,本来预期只需要写入100次合计10000条数据,实际写入了100次×10000条=100万条数据,总写入量直接放大了100倍,自然会感知到速度骤降。
  • 改用多进程后没有出现速度下降属于巧合:大概率是测试时你清空了之前的错误缓存文件,且没有运行后续的加载-重存逻辑,总写入量没有持续叠加,才会误以为是多进程的性能优势解决了问题。如果保留错误逻辑,就算用多进程,只要重复运行几次加载存储流程,一样会出现速度爆炸式下降的问题。

修复方案如下:

  1. 把pickle.dump(saveCopy, filehandle)替换为pickle.dump(l, filehandle),修正分片写入逻辑
  2. 将pickle、sys等模块的导入语句移到文件头部,避免函数每次运行时重复导入的额外开销
  3. 写入新缓存分片前先清空旧缓存目录,避免旧的错误分片文件和新文件混淆,导致后续加载时数据重复

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 13:45:08