【问题标题】:Multithreaded MD5 Checksum in PythonPython中的多线程MD5校验和
【发布时间】:2012-04-12 19:58:52
【问题描述】:

我有一个 Python 脚本,它递归地遍历指定目录,并对找到的每个文件进行校验和。然后它会写入一个日志文件,其中列出了所有文件路径及其 md5 校验和。

因此,对于 50,000 个 15 MB 的文件,这需要很长时间。但是,我的计算机可用的资源比它实际使用的要多得多。如何调整我的方法以使脚本使用更多资源以更快地执行?

例如,我可以将我的文件列表分成三份并为每份运行一个线程,从而给我 3 倍的运行时间吗?

我对线程不太满意,我希望有人不介意为我的情况做个例子。

这是我的顺序 md5 循环的代码:

for (root, dirs, files) in os.walk(root_path):
    for filename in files:
        file_path = root + "/" + filename
        md5_pairs.append([file_path, md5file(file_path, 128)])

提前感谢您的帮助!

【问题讨论】:

  • 最简单的方法是启动你的 python 脚本的单独实例,其中每个实例都从 root_path 获得一个子树
  • 在尝试任何优化之前,最好先调查一下瓶颈在哪里。例如,如果 MD5 比从磁盘读取文件花费的时间要少得多,就速度而言不要期望太多。
  • 这很好,我对简单读取和校验和进行了基准测试,校验和只增加了大约 10% 的运行时间。我们的光纤连接 SAN 读取速度为 8 Gb/s。我想我可以让这些文件更快地读入,不是吗?要读取总共 7 GB 的 600 个文件,需要 88 秒。
  • 感谢大家的帮助! Stack Overflow 太棒了!!!

标签: python multithreading md5 checksum


【解决方案1】:

对于这种工作,我认为 multiprocessing.Pool 会给你带来更少的惊喜—— 查看http://docs.python.org/library/multiprocessing.html的示例和文档

【讨论】:

  • 嗨,jsbueno,我尝试按照建议使用池,但它仅将运行时间提高了 20%。这会更好吗?由于我正在处理大量小文件,将文件列表拆分成块并将每个块发送到池中会更好吗?还是最好将每个单独的 md5 调用发送到池中?
  • 您没有看到超过 20% 的加速的原因可能表明您的处理受 IO 限制而不是 CPU 限制。您应该进行一些分析以查看是否是这种情况,因为理论上您应该能够在计算部分获得 100% 的效率。
  • 如果它是 io 绑定的,您可以通过读取主进程(或其他)中的所有文件将它们放入 RAM 来改进。然后每个 md5'ing 进程将不必从磁盘 md5 加载,它只需要 md5。 (当然,假设您对此有记忆。)
  • 是的,我可能会用完内存,因为我正在检查几个 TB 的实时案例。不过我可以尝试一次加载块。
  • 原来我的情况的瓶颈是 IO。实际上,将 find 命令通过管道传输到 md5 命令比在 python 中步行、读取和 md5 快 23%。
【解决方案2】:

如果您要使用线程,您需要首先启动您的线程并让它们从 Queue.Queue 实例中轮询工作。然后在您的主线程中,运行您拥有的 for 循环,但不要调用 md5file(..),而是将所有参数推送到 Queue.Queue 上。 Threading / Queue in Python 有一个示例,但也请查看文档:http://docs.python.org/library/queue.html

【讨论】:

    【解决方案3】:

    GIL(全局解释器锁)线程不会很有帮助。您的应用程序永远不会同时执行对 md5.update 函数的多次调用。我会继续尝试优化改进您的进程池。

    【讨论】:

    • 如果 md5file 从磁盘读取,这不是真的。在磁盘 IO 期间不保留 GIL。话虽如此,线程是解决延迟问题比吞吐量问题更好的解决方案......
    • 是的,我想我使用了错误的术语。我想我想要的是多处理,而不是多线程。对吗?
    • 如果您受到大量 IO 限制,这不会有太大的不同,但 in_general 多处理是在 Python 中利用更多 CPU 内核的正确方法。
    • @thebjorn,但是在计算哈希值时 GIL 会被锁定,这可能比 IO 昂贵得多。
    • @mikerobi Nah,通常没有什么比 IO 更昂贵的了——说真的 :-) 根据 Jamie(上图)的说法,IO 占 90% 的时间。
    【解决方案4】:

    令人尴尬地并行并为一大块文件启动一个进程。我们在集群上执行此操作。您可以有几十个或数百个进程,每个 md5ing 几十个文件。届时,磁盘 IO 将成为您的瓶颈。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-02
      • 1970-01-01
      • 1970-01-01
      • 2016-01-18
      相关资源
      最近更新 更多