Closed tanhHeng closed 1 year ago
使用线程池,支持 enable_copy_file_range
选项,并暴露拷贝过程中出现的问题的参考实现:
def copy_tree_fast(src_path: str, dst_path: str, ignore=None, copy_function: Callable[[str, str], object] = shutil.copy2):
with ThreadPoolExecutor(max_workers=max(1, config.copy_thread_active), thread_name_prefix='QBMFileCopier') as pool:
def threaded_copy(s: str, d: str):
tasks.append((s, d, pool.submit(copy_function, s, d)))
tasks = []
shutil.copytree(src_path, dst_path, ignore=ignore, copy_function=threaded_copy)
# expose the possible exceptions
for src, dst, future in tasks:
try:
future.result()
except Exception:
server_inst.logger.error('Failed to copy file from {} to {}'.format(src, dst))
raise
@@ -130,7 +148,7 @@
server_inst.logger.info('copying {} -> {}'.format(src_path, dst_path))
if os.path.isdir(src_path):
- shutil.copytree(src_path, dst_path, ignore=lambda path, files: set(filter(config.is_file_ignored, files)), copy_function=copy_file_fast)
+ copy_tree_fast(src_path, dst_path, ignore=lambda path, files: set(filter(config.is_file_ignored, files)), copy_function=copy_file_fast)
elif os.path.isfile(src_path):
dst_dir = os.path.dirname(dst_path)
if not os.path.isdir(dst_dir):
已于 f39a393a1afa48e5de3606ca6d8826519dd471e2 中实现并行复制
多线程在Windows平台
普通的copytree等复制函数在Windows平台上调度性能较差,无法充分利用硬盘。 使用多线程可将速度提升约300%-600%
添加内容
函数
通过使用
shutil.copytree
函数先获取文件列表,threading
模块建立线程,将待复制的文件按照线程数切分成n份分配给各个线程,开始计算 极大的提高了Windows平台上的备份速度Config
copy_thread_active
默认值:
4
建立多个线程同时请求硬盘以加快复制速度,该选项控制了建立的线程数量
当该选项设定为0时,关闭多线程复制而采用传统复制方式
测试
环境:
结果:
速度提升了约300%-600%