Python3 多程序
阿新 • • 發佈:2021-06-18
什麼是程序?
-
程式:一個未執行的二進位制檔案,叫做程式。如Windows下的PE檔案
-
程序:二進位制檔案執行後,檔案本身以及用到的資源稱為程序,他是作業系統分配資源的基本單元。
-
多工:不止可以通過執行緒完成多工,還可以通過程序完成多工。
使用Process實現多程序
from multiprocessing import Process import time def test(test): time.sleep(5) print("這是{}".format(test)) def main(): p1 = Process(target=test,kwargs={"test":"t1"}) p2 = Process(target=test,kwargs={"test":"t2"}) p1.start() p2.start() if __name__ == "__main__": main()
通過佇列完成程序間通訊
from multiprocessing import Queue,Process import time import os def queue_put(q): for i in range(10): q.put(i) print("PID:{} ,{} 已存入佇列,當前佇列共{}個元素".format(os.getpid(),i,q.qsize())) time.sleep(5) def queue_get(q): for i in range(10): print("PID:{} ,{} 已取出佇列,當前佇列共{}個元素".format(os.getpid(),q.get(),q.qsize())) time.sleep(5) def main(): q = Queue(5)#建立一個佇列,佇列可以儲存5個數據 # q.put("a")#向佇列中新增資料,如果佇列存滿,程式會阻塞等待 # q.get()#從佇列中獲取資料,如果佇列為空,程式會阻塞等待 # #q.put_nowait()如果佇列存滿,程式會報異常 # #q.get_nowait()如果佇列為空,程式會報異常 # q.qsize()#取出佇列中資料個數 # q.empty()#判斷佇列是否為空 # q.full()#判斷佇列是否存滿 p1 = Process(target=queue_put,args=(q,)) p2 = Process(target=queue_get,args=(q,)) p1.start() p2.start() if __name__ == "__main__": main()
程序池
import hashlib from multiprocessing import Pool def js_hash(s): md5 = hashlib.md5() md5.update(s.encode('utf-8')) md5 = md5.hexdigest() if '0e' == md5[0:2] and md5[2:].isdecimal(): print(s,md5) if __name__ == '__main__': p = Pool(5)#建立一個程序池,最大程序數5,如果不填,則無限制 for i in range(0,99999999999999): s = '0e' + str(i) p.apply_async(js_hash, args=(s,))#apply_async(要呼叫的目標,args=(傳遞的引數,)) p.close()#關閉程序池,關閉後進程池不再接受新的請求 p.join()#等待所有子程序執行完畢,必須放在close語句後
案例:多工檔案copy
import os,sys
from multiprocessing import Pool,Manager
def copy_file(q,file_name,old_dir,new_dir):
#print("將 {} 檔案複製到 {} 目錄下".format(file_name,new_dir))
if os.path.isdir(old_dir + "\\" + file_name):
# print(file_name,"是個目錄")
q.put(file_name)
else:
#print(file_name,"是個檔案")
with open(old_dir + "\\" + file_name,'rb') as file:
with open(new_dir + "\\" + file_name,"wb") as file_new:
file_new.write(file.read())
def main():
# 1、獲取要拷貝的檔名
print("注意!此程式不完善,尚不能copy資料夾中資料夾的檔案")
old_dir = input(r"輸入需要copy的原始檔夾路徑,如(C:\null):")
# 2、建立新資料夾
new_dir = input(r"輸入需要copy的目標資料夾路徑,如(C:\null_副件):")
try:
os.mkdir(new_dir)
except:
pass
# 3、獲取所有需要copy檔名
files_name = os.listdir(old_dir)
# 4、建立程序池
po = Pool(5)
# 程序池使用佇列需要使用Manager類下的Queue
q = Manager().Queue()
# 5、向程序池新增複製檔案的任務
for file_name in files_name:
po.apply_async(copy_file,args=(q,file_name,old_dir,new_dir))
po.close()
#po.join()
copy_ok = 0
copy_num = len(files_name)
folders = []
while True:
copy_ok += 1
sys.stdout.write("\r拷貝進度:{:.2f}%".format(copy_ok*100/copy_num))
try:
folders.append(q.get_nowait())
except:
pass
#將未拷貝的資料夾存入列表
if copy_ok >= copy_num:
break
print("\n以下資料夾未複製:",",".join(folders))
if __name__ == "__main__":
main()