使用线程池并从主进程向文件写入是收集并行 md5sum 子进程输出的简单方法:
from multiprocessing.dummy import Pool
from subprocess import check_output
def md5sum(filename):
try:
return check_output(["md5sum", filename]), None
except Exception as e:
return None, e
if __name__ == "__main__":
p = Pool(number_of_processes)
with open("md5sums.txt", "wb") as logfile:
for output, error in p.imap(md5sum, filenames):
if error is None:
logfile.write(output)
md5sum
的输出很小,因此可以将其存储在内存中
imap
保留顺序
number_of_processes
可能与文件数或CPU核心数不同(更大的值并不意味着更快:它取决于IO(磁盘)和CPU相对性能的关系)
您可以尝试一次性传递多个文件给md5sum子进程。
在这种情况下,您不需要外部的子进程;您可以在Python中计算md5:
import hashlib
from functools import partial
def md5sum(filename, chunksize=2**15, bufsize=-1):
m = hashlib.md5()
with open(filename, 'rb', bufsize) as f:
for chunk in iter(partial(f.read, chunksize), b''):
m.update(chunk)
return m.hexdigest()
为了使用多个进程而不是线程(以允许纯Python
md5sum()
在利用多个CPU并行运行),只需从上面代码中的导入中删除
.dummy
即可。
要使用多个进程而非线程(以便利用多个CPU并行运行纯Python md5sum()
),只需从上述代码中的导入中删除.dummy
即可。
processes[]
将保留files_output[]
的原始顺序,并确保每个 md5sum 进程都已完成。但如果您担心操作系统的资源,您应该考虑使用任务队列和线程池,并在每个线程中同步运行 md5sum,如 @Alfe 建议的那样,使用subprocess.check_output()
。 - dkz