Python Process多進程實現(xiàn)過程
進程的概念
程序是沒有運行的代碼,靜態(tài)的;
進程是運行起來的程序,進程是一個程序運行起來之后和資源的總稱;
程序只有一個,但同一份程序可以有多個進程;例如,電腦上多開QQ;
程序和進程的區(qū)別在于有沒有資源,進程有資源而程序沒有資源,進程是一個資源分配的基本單元;
程序在沒運行的時候沒有資源,沒有顯卡,沒有網(wǎng)卡,等等;雙擊運行后有攝像頭,有網(wǎng)速等等,就叫做進程;
進程的狀態(tài)
進程狀態(tài)圖

- 就緒態(tài):運行的條件都已經(jīng)慢去,正在等在cpu執(zhí)行
- 執(zhí)行態(tài):cpu正在執(zhí)行其功能
- 等待態(tài):等待某些條件滿足,例如一個程序sleep了,此時就處于等待態(tài)
使用Process完成多任務(wù)
進程的使用步驟和線程的使用步驟基本一致;
進程的使用步驟:
- 導(dǎo)入multiprocessing;
- 編寫多任務(wù)所所需要的函數(shù);
- 創(chuàng)建multiprocessing.Process類的實例對象并傳入函數(shù)引用;
- 調(diào)用實例對象的start方法,創(chuàng)建子線程。
進程使用步驟圖示:

進程使用步驟代碼
import time
import multiprocessing
def sing():
while True:
print("-----sing-----")
time.sleep(1)
def dance():
while True:
print("-----dance-----")
time.sleep(1)
def main():
p1 = multiprocessing.Process(target=sing)
p2 = multiprocessing.Process(target=dance)
p1.start()
p2.start()
if __name__ == "__main__":
main()
運行結(jié)果:
-----sing----- -----dance----- -----sing----- -----dance----- -----sing----- -----dance----- ......
進程:
- 主進程有什么,子進程就會有什么資源;
- 線程能創(chuàng)建多任務(wù),進程也能創(chuàng)建多任務(wù),但進程耗費的資源比較大;
- 所以運行的進程數(shù),不一定越多越好;
- 當(dāng)創(chuàng)建子進程時,會復(fù)制一份主進程的資源,代碼,內(nèi)存等,但又會有自己不同的地方,比如pid等;
- 我們可以理解為多進程之間共享代碼,即只有一份代碼,但有多個指向同一代碼的箭頭;
- 能共享的就共享,不能共享的就拷貝一份;不需要修改的就共享,要修改的時候就給你拷貝一份,這就是寫時拷貝;
獲取進程id
獲取進程id代碼
from multiprocessing import Process
import osdef run_proc():
"""子進程要執(zhí)行的代碼"""
print('子進程運行中,pid=%d...' % os.getpid()) # os.getpid獲取當(dāng)前進程的進程號
print('子進程將要結(jié)束...')
if __name__ == '__main__':
print('父進程pid: %d' % os.getpid()) # os.getpid獲取當(dāng)前進程的進程號
p = Process(target=run_proc)
p.start()
進程和線程對比
進程和線程的區(qū)別
- 進程是系統(tǒng)進行資源分配和調(diào)度的一個獨立單位;
- 線程是進程的一個實體,是CPU調(diào)度和分派的基本單位,即是操作系統(tǒng)調(diào)度的單位,它是比進程更小的能獨立運行的基本單位;
- 一個程序至少有一個進程,一個進程至少有一個線程;
- 線程的劃分尺度小于進程(資源比進程少),使得多線程程序的并發(fā)性高;
- 進程在執(zhí)行過程中擁有獨立的內(nèi)存單元,而多個線程共享內(nèi)存,從而極大地提高了程序的運行效率;
- 線程不能夠獨立執(zhí)行,必須依存在進程中;
- 進程先有,才有的線程;
- 線程用資源去做事;
- 多線程能實現(xiàn)多任務(wù)是指在一個進程資源里面有多個箭頭;多線程是在同一個資源里面有多個箭頭執(zhí)行同一份代碼;
- 多進程的多任務(wù)是又開啟了一份資源,在這個資源里面又有一個箭頭;
- 進程執(zhí)行方式1:在一份資源里面有多個箭頭在執(zhí)行;
- 進程執(zhí)行方式2:有多份資源,在每一份資源里面有一個箭頭執(zhí)行代碼;
- 線程執(zhí)行開銷小,但不利于資源的管理和保護,進程正好相反;
- 開發(fā)中還是多線程用的多;
通過隊列完成進程間通信
隊列使用語法
# 創(chuàng)建隊列: from multiprocessing import Queue q = Queue(3) # 往隊列中添加數(shù)據(jù): q.put(xxx) # 從隊列中獲取數(shù)據(jù): q.get()
通過隊列完成進程間通信代碼
from multiprocessing import Queue
import multiprocessing
def download_data(q):
"""模擬這是從網(wǎng)上下載數(shù)據(jù)"""
data = [11, 22, 33]
for i in data:
q.put(i)
print("數(shù)據(jù)下載完成")
def deal_data(q):
"""模擬處理從網(wǎng)上下載下來的數(shù)據(jù)"""
data_list = []
while True:
data = q.get()
data_list.append(data)
if q.empty():
break
print("處理數(shù)據(jù)結(jié)束,數(shù)據(jù)為:", data_list)
def main():
q = Queue(3)
p1 = multiprocessing.Process(target=download_data, args=(q,))
p2 = multiprocessing.Process(target=deal_data, args=(q,))
p1.start()
time.sleep(1)
p2.start()
if __name__ == '__main__':
main()
運行結(jié)果:
數(shù)據(jù)下載完成
處理數(shù)據(jù)結(jié)束,數(shù)據(jù)為: [11, 22, 33]
進程池完成多任務(wù)
進程池
進程池的概念
因為進程的創(chuàng)建和銷毀是需要大量的資源的,為了減少消耗,當(dāng)我們在處理多任務(wù)時,比如100個任務(wù),我們可以先創(chuàng)建10個進程,然后用這10個進程來執(zhí)行者100個任務(wù),就可以重復(fù)使用進程,達到節(jié)約資源的目的了,而這個就可以使用進程池。
進程池的創(chuàng)建
任務(wù)數(shù)固定且較少,用普通的進程即可;任務(wù)數(shù)不確定,且比較多,就用進程池;
進程池不會等待進程執(zhí)行完畢,我們需要使用po.join()讓主進程等待進程池中的進程執(zhí)行完;且po.close()必須在join前面;小編整理一套Python資料和PDF,有需要Python學(xué)習(xí)資料可以加學(xué)習(xí)群:631441315 ,反正閑著也是閑著呢,不如學(xué)點東西啦~~
創(chuàng)建進程池語法
# 創(chuàng)建進程池 from multiprocessing import Pool po = Pool(3) # 給進程池傳遞任務(wù)和參數(shù) po.asyn(sing, (num,)) # 讓進程池等待子進程執(zhí)行完 po.close() po.join()
進程池pool示例
from multiprocessing import Pool
import os, time, random
def worker(msg):
t_start = time.time()
print("%s開始執(zhí)行,進程號為%d" % (msg, os.getpid()))
# random.random()隨機生成0~1之間的浮點數(shù)
time.sleep(random.random() * 2)
t_stop = time.time()
print(msg, "執(zhí)行完畢,耗時%0.2f" % (t_stop - t_start))
def main():
po = Pool(3) # 定義一個進程池,最大進程數(shù)3
for i in range(0, 10):
# Pool().apply_async(要調(diào)用的目標(biāo),(傳遞給目標(biāo)的參數(shù)元祖,))
# 每次循環(huán)將會用空閑出來的子進程去調(diào)用目標(biāo)
po.apply_async(worker, (i,))
print("----start----")
po.close() # 關(guān)閉進程池,關(guān)閉后po不再接收新的請求
po.join() # 等待po中所有子進程執(zhí)行完成,必須放在close語句之后
print("-----end-----")
if __name__ == '__main__':
main()
執(zhí)行結(jié)果:
----start---- 0開始執(zhí)行,進程號為7812 1開始執(zhí)行,進程號為9984 2開始執(zhí)行,進程號為1692 執(zhí)行完畢,耗時0.65 3開始執(zhí)行,進程號為9984 執(zhí)行完畢,耗時1.08 4開始執(zhí)行,進程號為7812 執(zhí)行完畢,耗時1.82 5開始執(zhí)行,進程號為1692 執(zhí)行完畢,耗時1.12 6開始執(zhí)行,進程號為7812 執(zhí)行完畢,耗時1.35 7開始執(zhí)行,進程號為9984 執(zhí)行完畢,耗時0.11 8開始執(zhí)行,進程號為9984 執(zhí)行完畢,耗時0.50 9開始執(zhí)行,進程號為7812 執(zhí)行完畢,耗時0.65 執(zhí)行完畢,耗時0.70 執(zhí)行完畢,耗時0.74 -----end-----
多進程拷貝文件夾
多任務(wù)文件夾copy
步驟思路:
1.獲取用戶要拷貝的文件夾的名字;
2.創(chuàng)建一個新的文件夾;
3.獲取文件夾的所有待拷貝的文件名;listdir()
4.創(chuàng)建進程池;
5.復(fù)制原文件夾中的文件,到新文件夾的文件中去;
多任務(wù)拷貝文件代碼
import os
from multiprocessing import Pool
def copy_file(file, old_folder, new_folder):
old_f = open(old_folder+"/"+file, "rb")
data = old_f.read()
old_f.close()
new_f = open(new_folder+"/"+file, "wb")
new_f.write(data)
new_f.close()
print("創(chuàng)建文件成功:", file)
def main():
# 1.獲取要拷貝的文件夾
old_folder = input("請輸入你要拷貝的文件夾:")
# 2.創(chuàng)建新文件夾
new_folder = old_folder + "_復(fù)件"
try:
os.mkdir(new_folder)
print("創(chuàng)建文件夾成功")
except Exception as e:
pass
# 3.獲取文件夾中所有待拷貝的文件,listdir()
files_list = os.listdir(old_folder)
# print(files_list)
# 4.創(chuàng)建進程池
po = Pool(5)
for file in files_list:
# 向進程池中添加復(fù)制文件的任務(wù)
po.apply_async(copy_file, args=(file, old_folder, new_folder))
# 復(fù)制原文件夾中的文件,到新文件夾中
po.close()
po.join()
if __name__ == '__main__':
main()
在完成文件夾拷貝后,增加了一個需求,顯示拷貝文件的進度條,怎么辦?
多任務(wù)拷貝文件并顯示進度條
如果要在進程池中使用Queue,要使用from multiprocessing import Manager ,使用Manager().Queue();
顯示進度條思路:
- 創(chuàng)建一個隊列;
- 往拷貝文件的函數(shù)中傳入隊列,拷貝好一個文件就往q中傳入該文件名;
- 在主函數(shù)中計算listdir()中的所有文件數(shù)量;
- 在主函數(shù)中定義一個num,初始值為0;
- 在主函數(shù)中定義一個while true,從q中獲取文件每獲取一個文件們就將num+1
- 計算,如果num的值大于等于總文件數(shù)量,就break;
- 使用已拷貝文件數(shù)量num除以總文件數(shù)量,即為拷貝的進度,使用開頭\r 和end=""讓顯示進度不換行,如下:
print("\r已拷貝文件%.2f %%" % (copy_ok_file_num*100/all_file_len), end="")
多任務(wù)拷貝文件并顯示進度條代碼:
import os
from multiprocessing import Pool, Manager
def copy_file(q, file, old_folder, new_folder):
old_f = open(old_folder+"/"+file, "rb")
data = old_f.read()
old_f.close()
new_f = open(new_folder+"/"+file, "wb")
new_f.write(data)
new_f.close()
q.put(file)
def main():
# 1.獲取要拷貝的文件夾
old_folder = input("請輸入你要拷貝的文件夾:")
# 2.創(chuàng)建新文件夾
new_folder = old_folder + "_復(fù)件"
try:
os.mkdir(new_folder)
print("創(chuàng)建文件夾成功")
except Exception as e:
pass
# 3.獲取文件夾中所有待拷貝的文件,listdir()
files_list = os.listdir(old_folder)
# 4.創(chuàng)建進程池
po = Pool(5)
# 5.創(chuàng)建隊列
q = Manager().Queue()
# 6.復(fù)制原文件夾中的文件,到新文件夾中
for file in files_list:
# 向進程池中添加復(fù)制文件的任務(wù)
po.apply_async(copy_file, args=(q, file, old_folder, new_folder))
all_file_len = len(files_list)
po.close()
# po.join()
copy_ok_file_num = 0
while True:
file = q.get()
copy_ok_file_num += 1
print("已拷貝文件%.2f %%" % (copy_ok_file_num*100/all_file_len))
# print("\r已拷貝文件%.2f %%" % (copy_ok_file_num*100/all_file_len), end="")
if copy_ok_file_num >= all_file_len:
break
print()
if __name__ == '__main__':
main()
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Python基于進程池實現(xiàn)多進程過程解析
- keras tensorflow 實現(xiàn)在python下多進程運行
- python實現(xiàn)多進程按序號批量修改文件名的方法示例
- python進程池實現(xiàn)的多進程文件夾copy器完整示例
- python 多進程并行編程 ProcessPoolExecutor的實現(xiàn)
- python multiprocessing多進程變量共享與加鎖的實現(xiàn)
- Python Multiprocessing多進程 使用tqdm顯示進度條的實現(xiàn)
- Python2.7實現(xiàn)多進程下開發(fā)多線程示例
- Python 多進程原理及實現(xiàn)
相關(guān)文章
Python列表排序 list.sort方法和內(nèi)置函數(shù)sorted用法
這篇文章主要介紹了Python列表排序 list.sort方法和內(nèi)置函數(shù)sorted用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03
Python中的裝飾器鏈(decorator chain)詳解
在Python中,裝飾器是一種高級功能,它允許你在不修改函數(shù)或類代碼的情況下,為它們添加額外的功能,裝飾器通常用于日志記錄、性能測量、權(quán)限檢查等場景,當(dāng)多個裝飾器應(yīng)用于同一個函數(shù)或類時,形成裝飾器鏈,這篇文章主要介紹了Python中的裝飾器鏈詳解,需要的朋友可以參考下2024-06-06
python設(shè)計并實現(xiàn)平面點類Point的源代碼
這篇文章主要介紹了python-設(shè)計并實現(xiàn)平面點類Point,定義一個平面點類Point,對其重載運算符關(guān)系運算符,關(guān)系運算以距離坐標(biāo)原點的遠近作為基準(zhǔn),需要的朋友可以參考下2024-05-05
Python分析特征數(shù)據(jù)類別與預(yù)處理方法速學(xué)
這篇文章主要為大家介紹了Python分析特征數(shù)據(jù)類別與預(yù)處理方法速學(xué),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02
Django之使用內(nèi)置函數(shù)和celery發(fā)郵件的方法示例
這篇文章主要介紹了Django之使用內(nèi)置函數(shù)和celery發(fā)郵件的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
python中數(shù)組和矩陣乘法及使用總結(jié)(推薦)
這篇文章主要介紹了python中數(shù)組和矩陣乘法及使用總結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05

