多任务(进程)案例----- 拷贝文件夹
import multiprocessing import os,time,random,sys from PyQt5.Qt import QApplication,QWidget,QFileDialog def getDir(): ''' 利用pyqt5 获取目录路径 return:str ''' app = QApplication(sys.argv) path = QFileDialog.getExistingDirectory() return path def copy_file(source_dir,file_name,dest_dir): ''' 具体的工作函数 :return:None ''' with open(source_dir+'/'+file_name,'r') as f_source,open(dest_dir+'/'+file_name,'w') as f_dest: text = f_source.read() f_dest.write(text) print("拷贝完成") def main(): #获取要复制的文件夹 source_dir = getDir() #目标文件夹 dest_dir = source_dir +"[副本6]" #创建文件夹 try: os.mkdir(dest_dir) except: print("文件夹已经存在") #获取这个文件夹中的所有普通文件名 file_names = os.listdir(source_dir) # print(file_names) #创建进程池 pool = multiprocessing.Pool(5) t1 = time.time() for file_name in file_names: pool.apply_async(copy_file,args=(source_dir,file_name,dest_dir)) pool.close() pool.join() print("总用时:{}".format(time.time()-t1)) if __name__ == '__main__': main() ''' 测试结果 下为进程池里进程的个数对时间的影响 (此时为 100 个文件) 1 0.6582393646240234 2 0.546534538269043 3 0.5874290466308594 5 0.6821753978729248 10 0.6153411865234375 下为进程池里进程的个数对时间的影响 (此时为 1000 个文件) 1 1.9657423496246338 2 1.3813047409057617 3 1.304509162902832 5 1.4211978912353516 10 1.2317066192626953 '''
改进版
加上完成进度
1 import multiprocessing 2 import os,time,random,sys 3 4 from PyQt5.Qt import QApplication,QWidget,QFileDialog 5 6 def getDir(): 7 ''' 8 利用pyqt5 获取目录路径 9 return:str 10 ''' 11 app = QApplication(sys.argv) 12 path = QFileDialog.getExistingDirectory() 13 return path 14 15 def copy_file(queue,source_dir,file_name,dest_dir): 16 ''' 17 具体的工作函数 18 :return:None 19 ''' 20 with open(source_dir+'/'+file_name,'r') as f_source,open(dest_dir+'/'+file_name,'w') as f_dest: 21 text = f_source.read() 22 f_dest.write(text) 23 time.sleep(1) 24 #发送拷贝完成的文件名 25 queue.put(file_name) 26 27 def prep_before_work(): 28 ''' 29 前期准备 30 return:str 31 ''' 32 #获取要复制的文件夹 33 source_dir = getDir() 34 35 #目标文件夹 36 dest_dir = source_dir +"[副本1]" 37 38 #创建文件夹 39 try: 40 os.mkdir(dest_dir) 41 except: 42 print("文件夹已经存在") 43 44 #获取这个文件夹中的所有普通文件名 45 return source_dir,os.listdir(source_dir),dest_dir 46 47 def print_rate(queue,file_names,): 48 all_file_num = len(file_names) 49 while True: 50 file_name = queue.get() 51 if file_name in file_names: 52 file_names.remove(file_name) 53 copy_rate = (all_file_num-len(file_names))*100/all_file_num 54 print("\r{:.2f}%...({})".format(copy_rate, file_name), end="") 55 if copy_rate >= 100: 56 break 57 58 def main(): 59 #前期准备, 60 source_dir,file_names,dest_dir= prep_before_work() 61 62 #创建进程池 63 pool = multiprocessing.Pool(5) 64 65 #主进程和 子进程间通信 (显示进度) ---使用Queue (不过在进程池中要使用Manager()对象的Queue()) 66 queue = multiprocessing.Manager().Queue() 67 68 for file_name in file_names: 69 pool.apply_async(copy_file,args=(queue,source_dir,file_name,dest_dir)) 70 pool.close() 71 # pool.join() #主进程 会阻塞在这, 不过此时不需要了,因为后面有循环了 72 73 print_rate(queue,file_names) 74 75 if __name__ == '__main__': 76 main()
终极版:
加上真正的进度条
import multiprocessing import os,time,random,sys from PyQt5.Qt import QApplication,QWidget,QFileDialog,QProgressBar,QTimer def getDir(): ''' 利用pyqt5 获取目录路径 return:str ''' app = QApplication(sys.argv) path = QFileDialog.getExistingDirectory() return path def copy_file(queue,source_dir,file_name,dest_dir): ''' 具体的工作函数 :return:None ''' with open(source_dir+'/'+file_name,'r') as f_source,open(dest_dir+'/'+file_name,'w') as f_dest: text = f_source.read() f_dest.write(text) time.sleep(1) #发送拷贝完成的文件名 queue.put(file_name) def prep_before_work(): ''' 前期准备 return:str ''' #获取要复制的文件夹 source_dir = getDir() #目标文件夹 dest_dir = source_dir +"[副本1]" #创建文件夹 try: os.mkdir(dest_dir) except: print("文件夹已经存在") #获取这个文件夹中的所有普通文件名 return source_dir,os.listdir(source_dir),dest_dir def print_rate(queue,file_names): all_file_num = len(file_names) while True: file_name = queue.get() if file_name in file_names: file_names.remove(file_name) rate.value = (all_file_num-len(file_names))*100/all_file_num print("\r{:.2f}%...({})".format(rate.value, file_name), end="") if rate.value >= 100: break def create_progressBar_to_show(rate): app = QApplication(sys.argv) progressBar = QProgressBar() progressBar.setFixedSize(300,30) progressBar.setWindowTitle("进度条") timer = QTimer() def test(): if rate.value>0: progressBar.show() progressBar.setValue(rate.value) if rate.value == 100: sys.exit(0) timer.timeout.connect(test) timer.start(100) sys.exit(app.exec_()) def main(): #前期准备, try: source_dir,file_names,dest_dir = prep_before_work() #创建进程池 pool = multiprocessing.Pool(5) #主进程和 子进程间通信 (显示进度) ---使用Queue (不过在进程池中要使用Manager()对象的Queue()) queue = multiprocessing.Manager().Queue() for file_name in file_names: pool.apply_async(copy_file,args=(queue,source_dir,file_name,dest_dir)) pool.close() # pool.join() #主进程 会阻塞在这, 不过此时不需要了,因为后面有循环了 print_rate(queue,file_names) except: print("出现异常,请检查...") if __name__ == '__main__': rate = multiprocessing.Value("d",0) process = multiprocessing.Process(target=create_progressBar_to_show,args=(rate,)) process.start() main()