最近在自学python,对多进程、多线程不熟悉,于是想自己整一段代码,通过不断地练习试错,来熟悉代码的执行逻辑。python模块的shutil.copytree可实现对文件夹的复制,但为了验证多进程速度提升是否明显,思路变通为将文件夹的所有文件进行遍历后,把要复制的文件夹路径、新路径组合放入队列,通过多进程从队列中取数据进行复制。受限于磁盘读写速度,有一定的提升。
'''
思路如下:
1、通过函数自定义函数get_all_sources遍历要复制的文件夹,取出所有路径
并生成新的路径组合,放入队列。
2、通过main函数从队列中取出路径,通过shutil.copy命令,开启多进程进行复制。
'''
import os
import shutil
import time
from multiprocessing import Process, Queue
def get_all_sources(sources_dir, destination, q):
for dirpath, dirnames, files in os.walk(sources_dir):#os.walk用来遍历文件夹,层层遍历
for file in os.scandir(dirpath):#对文件进行遍历,取出所有路径
if file.is_dir():#判断路径如为文件夹,则在目标路径下生成新文件夹
if not os.path.exists(os.path.join(destination ,file.path[3:])):
os.makedirs(os.path.join(destination ,file.path[3:]))
else:#将要复制的文件路径,新文件路径,组合成列表放入队列
q.put([file.path, os.path.join(destination ,file.path[3:])])#将
def main(q):
print('Copying,the present process is: %s' % os.getpid())
while True:
if q.qsize() == 0: break#判断队列是否为空,否则子进程无法结束
c = q.get()
shutil.copy(c[0], c[1])
if __name__ == "__main__":
q = Queue()
sources_dir = input('请输入要复制的文件夹的绝对路径:(举例:(D:\\要复制的文件夹):')
destination = input('请输入目标地址的绝对路径:(举例:D:\\目标地址文件夹):')
get_all_sources(sources_dir, destination, q)
start_time = time.time()
thread_list = [Process(target=main, args=(q,)) for i in range(12)]#开启的进程数,以CPU核心数开启。
for p in thread_list:
p.start()
for p in thread_list:
p.join()
end_time = time.time()
spend_time = (end_time - start_time)
print('Process ends', '一共用时{:.2f}秒'.format(spend_time))
测试结果如下:
从U盘上copy一个大小为26.5G的文件夹到电脑的SSD盘中,采用shutil.copytree命令直接执行,耗时3516秒(58分钟)。
采用上述代码执行,开启12个进程,耗时1651秒(27分钟)。
由此可见,多进程效率提升还是比较明显的。