Python使用multiprocessing實現(xiàn)多進程
一、進程概念
進程(Process)是資源分配的最小單位,它是操作系統(tǒng)進行資源分配和調(diào)度運行的基本單位,通俗理解:一個正在運行的程序就是一個進程。
注: 一個程序運行后至少有一個進程
二、python多進程
在python中使用多進程我們需要導入 multiprocessing 模塊
import multiprocessing
實例演示:
- 我們先定義兩個函數(shù),然后創(chuàng)建子進程去調(diào)用它們
import time
def mission1(n):
for i in range(1, n + 1):
print(f'第{i}次執(zhí)行任務一。')
time.sleep(0.2)
def mission2(n):
for i in range(1, n + 1):
print(f"第{i}次執(zhí)行任務二。")
time.sleep(0.2)
每個函數(shù)每次循環(huán)都sleep 0.2秒目的是為了之后演示進程之間是同步執(zhí)行的情況,否則程序運行太快沒辦法體現(xiàn)。
我們先試著直接調(diào)用它們:
mission1(5) mission2(5) """ 結(jié)果: 第1次執(zhí)行任務一。 第2次執(zhí)行任務一。 第3次執(zhí)行任務一。 第4次執(zhí)行任務一。 第5次執(zhí)行任務一。 第1次執(zhí)行任務二。 第2次執(zhí)行任務二。 第3次執(zhí)行任務二。 第4次執(zhí)行任務二。 第5次執(zhí)行任務二。 """
結(jié)果:先執(zhí)行了mission1 再執(zhí)行了mission2
- 子進程依賴于父進程創(chuàng)建,因而我們要創(chuàng)建兩個子進程,那么必須在父進程里面去創(chuàng)建。
python運行文件的時候會創(chuàng)建一個主進程也就是 MainProcess,因而我們必須在main里面去操作子進程:
if __name__ == '__main__': pass
- 接著我們創(chuàng)建子進程對象:
if __name__ == '__main__':
p1 = multiprocessing.Process(target=mission1, args=(5,))
p2 = multiprocessing.Process(target=mission2, kwargs={'n': 5})
multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}) :
target—表示調(diào)用對象,即子進程要執(zhí)行的任務(回調(diào)函數(shù)入口地址)
args—表示以元組的形式向子任務函數(shù)傳參,元組方式傳參一定要和參數(shù)的順序保持一致
kwargs—表示以字典的方式給子任務函數(shù)傳參,字典方式傳參字典中的key要和參數(shù)名保持一致
name—為子進程的名稱
進程運行:
p1.start() p2.start()
- 完整代碼:
import multiprocessing
import time
def mission1(n):
for i in range(1, n + 1):
print(f'第{i}次執(zhí)行任務一。')
time.sleep(0.2)
def mission2(n):
for i in range(1, n + 1):
print(f"第{i}次執(zhí)行任務二。")
time.sleep(0.2)
if __name__ == '__main__':
p1 = multiprocessing.Process(target=mission1, args=(5,)) # 注意單元素的元組格式
p2 = multiprocessing.Process(target=mission2, kwargs={'n': 5})
p1.start()
p2.start()
"""
結(jié)果:
第1次執(zhí)行任務一。
第1次執(zhí)行任務二。
第2次執(zhí)行任務一。
第2次執(zhí)行任務二。
第3次執(zhí)行任務一。
第3次執(zhí)行任務二。
第4次執(zhí)行任務一。
第4次執(zhí)行任務二。
第5次執(zhí)行任務一。
第5次執(zhí)行任務二。
"""
結(jié)果顯示:兩個函數(shù)在兩個子進程中同時執(zhí)行。(每次執(zhí)行順序可能有略微差別)
獲取進程信息
current_process()
獲取當前進程的信息:name(進程名稱) 和 pid (進程ID)
def mission1(user, n):
print(f"mission-1子進程:{multiprocessing.current_process().name}")
print(f"mission-1子進程ID:{multiprocessing.current_process().pid}")
for i in range(1, n + 1):
print(f"用戶{user}正在第{i}次執(zhí)行任務一。")
time.sleep(0.2)
OS 模塊
可以使用os模塊中的getpid()獲取當前進程的ID 以及 getppid()獲取當前進程的父進程ID。
import os
def mission2(user, n):
print(f"mission-2子進程:{multiprocessing.current_process().name}")
print(f"mission-2子進程ID:{os.getpid()}")
print(f"mission-2子進程的父進程為:{os.getppid()}")
for i in range(1, n + 1):
print(f"用戶{user}正在第{i}次執(zhí)行任務二。")
time.sleep(0.2)
完整代碼:
import multiprocessing
import time
import os
def mission1(user, n):
print(f"mission-1子進程:{multiprocessing.current_process().name}")
print(f"mission-1子進程ID:{multiprocessing.current_process().pid}")
print(f"mission-1子進程的父進程為:{os.getppid()}")
for i in range(1, n + 1):
print(f"用戶{user}正在第{i}次執(zhí)行任務一。")
time.sleep(0.2)
def mission2(user, n):
print(f"mission-2子進程:{multiprocessing.current_process().name}")
print(f"mission-2子進程ID:{os.getpid()}")
print(f"mission-2子進程的父進程為:{os.getppid()}")
for i in range(1, n + 1):
print(f"用戶{user}正在第{i}次執(zhí)行任務二。")
time.sleep(0.2)
if __name__ == '__main__':
print(f"主進程的ID為:{multiprocessing.current_process().pid}")
print(f"主進程的父進程ID為:{os.getppid()}")
print(f'--------主進程{multiprocessing.current_process().name}開始執(zhí)行--------')
p1=multiprocessing.Process(target=mission1,name='mission-1',args=('張三',5))
p2=multiprocessing.Process(target=mission2,name='mission-2',args=('李四',5))
p1.start()
p2.start()
"""
主進程的ID為:7500
主進程的父進程ID為:39284
--------主進程MainProcess開始執(zhí)行--------
mission-2子進程:mission-2
mission-2子進程ID:40552
mission-2子進程的父進程為:7500
用戶李四正在第1次執(zhí)行任務二。
mission-1子進程:mission-1
mission-1子進程ID:46296
mission-1子進程的父進程為:7500
用戶張三正在第1次執(zhí)行任務一。
用戶李四正在第2次執(zhí)行任務二。
用戶張三正在第2次執(zhí)行任務一。
用戶李四正在第3次執(zhí)行任務二。
用戶張三正在第3次執(zhí)行任務一。
用戶李四正在第4次執(zhí)行任務二。
用戶張三正在第4次執(zhí)行任務一。
用戶李四正在第5次執(zhí)行任務二。
用戶張三正在第5次執(zhí)行任務一。
"""
兩個子進程的父ID是相同的就是MainProcess這個主進程的ID
三、進程特點
- 多進程之間不會共享全局變量
- 主進程會默認等待子進程結(jié)束而結(jié)束 但可以通過設置來讓子進程跟著主進程結(jié)束而結(jié)束
正常情況:
import multiprocessing
import time
def mission1(user, n):
for i in range(1, n + 1):
print(f"用戶{user}正在第{i}次執(zhí)行任務一。")
time.sleep(0.1)
if __name__ == '__main__':
print(f'--------主進程{multiprocessing.current_process().name}開始執(zhí)行--------')
p1 = multiprocessing.Process(target=mission1, name='mission-1', args=('張三', 5))
p1.start()
time.sleep(0.4) # 讓主進程多執(zhí)行一會兒
print(f'----------主進程:{multiprocessing.current_process().name}最后一行代碼執(zhí)行完畢---------')
"""
--------主進程MainProcess開始執(zhí)行--------
用戶張三正在第1次執(zhí)行任務一。
用戶張三正在第2次執(zhí)行任務一。
----------主進程:MainProcess最后一行代碼執(zhí)行完畢---------
用戶張三正在第3次執(zhí)行任務一。
用戶張三正在第4次執(zhí)行任務一。
用戶張三正在第5次執(zhí)行任務一。
"""
正常情況下,主進程(最后一行代碼執(zhí)行完了)仍然會等待子進程(p1 mission-1)執(zhí)行完畢.
使用守護進程或者終止進程
import multiprocessing
import time
def mission1(user, n):
for i in range(1, n + 1):
print(f"用戶{user}正在第{i}次執(zhí)行任務一。")
time.sleep(0.1)
if __name__ == '__main__':
print(f'--------主進程{multiprocessing.current_process().name}開始執(zhí)行--------')
p1 = multiprocessing.Process(target=mission1, name='mission-1', args=('張三', 5))
# 方式1: 開啟子進程前提前設置守護主進程
p1.daemon = True
p1.start()
time.sleep(0.4) # 讓主進程多執(zhí)行一會兒
# p1.terminate()
print(f'----------主進程:{multiprocessing.current_process().name}最后一行代碼執(zhí)行完畢---------')
"""
--------主進程MainProcess開始執(zhí)行--------
用戶張三正在第1次執(zhí)行任務一。
用戶張三正在第2次執(zhí)行任務一。
----------主進程:MainProcess最后一行代碼執(zhí)行完畢---------
"""
我們發(fā)現(xiàn)子進程還沒執(zhí)行結(jié)束就被終止了。
- 多進程之間是無序的
以上就是Python使用multiprocessing實現(xiàn)多進程的詳細內(nèi)容,更多關(guān)于Python multiprocessing多線程的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python分批定量讀取文件內(nèi)容,輸出到不同文件中的方法
今天小編就為大家分享一篇python分批定量讀取文件內(nèi)容,輸出到不同文件中的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12
Python鍵鼠操作自動化庫PyAutoGUI簡介(小結(jié))
這篇文章主要介紹了Python鍵鼠操作自動化庫PyAutoGUI簡介,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-05-05
Python Tkinter創(chuàng)建GUI應用程序的示例
Tkinter提供了豐富的功能和靈活的接口,讓開發(fā)者能夠輕松地構(gòu)建出各種各樣的圖形用戶界面,本文介紹了使用Python的Tkinter庫創(chuàng)建圖形用戶界面GUI應用程序,感興趣的可以了解一下2024-12-12
使用pytorch搭建AlexNet操作(微調(diào)預訓練模型及手動搭建)
今天小編就為大家分享一篇使用pytorch搭建AlexNet操作(微調(diào)預訓練模型及手動搭建),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01
Python調(diào)用ffmpeg開源視頻處理庫,批量處理視頻
本文主要介紹了如何用Python調(diào)用ffmpeg開源視頻處理庫,來實現(xiàn)視頻批量的處理:水印、背景音樂、剪輯、合并、幀率、速率、分辨率等操作2020-11-11
150行Python代碼實現(xiàn)帶界面的數(shù)獨游戲
這篇文章主要介紹了150行Python代碼實現(xiàn)帶界面的數(shù)獨游戲,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-04-04
Python利用Matplotlib庫實現(xiàn)繪制餅形圖
這篇文章主要為大家分享了基于python+matplotlib庫的餅形圖繪制,具體內(nèi)容涉及一般的餅圖、分裂餅圖、以及環(huán)形圖,感興趣的小伙伴可以了解一下2022-04-04

