Python日常筆記(25)- 進程池

進程池

當需要創建的子進程數量不多時,可以直接利用multiprocessing中的Process動態成生多個進程,但如果是上百甚至上千個目標,手動的去創建進程的工作量巨大,此時就可以用到multiprocessing模塊提供的Pool方法。
初始化Pool時,可以指定一個最大進程數,當有新的請求提交到Pool中時,如果池還沒有滿,那麼就會創建一個新的進程用來執行該請求;但如果池中的進程數已經達到指定的最大值,那麼該請求就會等待,直到池中有進程結束,纔會用之前的進程來執行新的任務

用進程池來實現一個文件拷貝的案例:

import multiprocessing
import time
import os
# 讀寫文件
def copy_file(temp_file_dir_path, new_dir_path, file_name):
   data = None
   # 讀取文件
   with open(temp_file_dir_path, "rb") as f_read:
       data = f_read.read()

   if data:
       # 寫入文件
       new_dir_path += "\\" + file_name
       f_write = open(new_dir_path, "wb")
       f_write.write(data)
       f_write.close()
       time.sleep(1)

# 遞歸獲取文件
def get_copy_file(dict1, dir_path, po, new_dir_path):
   """
   :param dir_path:原始文件夾路徑
   :param po:進程池
   :param new_dir_path:新文件夾路徑
   :return:
   """
   # 獲取文件夾中的所有文件
   file_names = os.listdir(dir_path)
   for file_name in file_names:
       # 文件或者文件夾目錄
       temp_file_dir_path = dir_path + "\\" + file_name
       # 判斷是否是文件夾,如果是就遞歸
       if os.path.isdir(temp_file_dir_path):
           # 如果是文件夾直接遞歸在次掃描文件,並且將新地址重新整合,以及創建新文件夾
           # 這裏不能使用加等於,因爲有多個文件夾的話將會出現不停的疊加字符串導致路徑不對
           new_dest_dir_path = new_dir_path + "\\" + file_name
           # print(new_dest_dir_path)
           # 創建新文件夾
           os.mkdir(new_dest_dir_path)
           # 然後開始遞歸
           get_copy_file(dict1, temp_file_dir_path, po, new_dest_dir_path)
       # 判斷是否是文件,是文件就執行copy功能
       elif os.path.isfile(temp_file_dir_path):
           # 儲存文件名
           dict1["queue"].put(file_name)
           dict1["len"] += 1
           # 使用進程池來copy文件
           po.apply_async(copy_file, args=(temp_file_dir_path, new_dir_path, file_name))

# 進程池copy
def main():
   dir_path = "D:\視頻\Python\python筆記"
   new_dir_path = dir_path + "【new】"
   try:
       # 創建新文件夾
       os.mkdir(new_dir_path)
   except:
       pass
   # 創建進程池
   po = multiprocessing.Pool(5)
   # 使用queue來實現進度條
   dict1 = multiprocessing.Manager().dict()
   q = multiprocessing.Manager().Queue()
   # 來儲存文件名和文件數量
   dict1["queue"] = q
   dict1["len"] = 0
   print(dict1)
   # 獲取要複製的文件並且複製
   get_copy_file(dict1, dir_path, po, new_dir_path)
   # 關閉子進程
   po.close()
   # 等待子進程完結後在結束主進程
   # po.join()
   break_count = 0
   while True:
       break_count += 1
       file_name = dict1["queue"].get()
       # 如果複製的數據數量與總數一致則表示已經複製完成,可以跳出循環
       num = break_count / dict1["len"]
       print(f"拷貝進度爲:%% %.2f 文件名爲:{file_name}" % (num * 100))
       if dict1["len"] <= break_count:
           break
       print(dict1["len"])

if __name__ == "__main__":
   main()

作者:阿超
原創公衆號:『Python日常筆記』,專注於 Python爬蟲等技術棧和有益的程序人生,會將一些平時的日常筆記都慢慢整理起來,也期待你的關注和阿超一起學習,公衆號回覆【csdn】優質資源。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章