進程創建方法
1. 流程特點
【1】 將需要子進程執行的事件封裝爲函數
【2】 通過模塊的Process類創建進程對象,關聯函數
【3】 可以通過進程對象設置進程信息及屬性
【4】 通過進程對象調用start啓動進程
【5】 通過進程對象調用join回收進程
2. 基本接口使用
Process()
功能 : 創建進程對象
參數 : target 綁定要執行的目標函數
args 元組,用於給target函數位置傳參
kwargs 字典,給target函數鍵值傳參
p.start()
功能:啓動進程
注意:啓動進程此時target綁定函數開始執行,該函數作爲子進程執行內容,此時進程真正被創建
p.join([timeout])
功能:阻塞等待回收進程
參數:超時時間
注意
【1】使用multiprocessing創建進程同樣是子進程複製父進程空間代碼段,父子進程運行互不影響。
【2】子進程只運行target綁定的函數部分,其餘內容均是父進程執行內容。
【3】multiprocessing中父進程往往只用來創建子進程回收子進程,具體事件由子進程完成。
【4】multiprocessing創建的子進程中無法使用標準輸入
示例1
import multiprocessing as mp
from time import sleep
def fun():
print("子進程開始")
sleep(3)
print("子進程結束")
if __name__ == '__main__':
# 創建進程對象
p = mp.Process(target=fun)
# 啓動進程
p.start()
# 回收進程
p.join()
示例2
from multiprocessing import Process
import os
from time import sleep
def fun1():
sleep(4)
print("喫飯", os.getpid(), os.getppid())
def fun2():
sleep(2)
print("睡覺", os.getpid(), os.getppid())
def fun3():
sleep(5)
print("打豆豆", os.getpid(), os.getppid())
if __name__ == '__main__':
fun_list = [fun1, fun2, fun3]
jobs = []
for f in fun_list:
p = Process(target=f)
jobs.append(p)
p.start()
for i in jobs:
i.join()
# 總耗時5s
示例3
from multiprocessing import Process
from time import sleep
# 帶參數的進程函數
def worker(sec, name):
for i in range(3):
sleep(sec)
print("I'm %s" % name)
print("I'm working...")
if __name__ == '__main__':
# p = Process(target=worker, args=(2, "Baron"))
p = Process(target=worker, kwargs={"name": "Abby", "sec": 2})
p.start()
p.join()
3. 進程對象屬性
p.name 進程名稱
p.pid 對應子進程的PID號
p.is_alive() 查看子進程是否在生命週期
p.daemon 設置父子進程的退出關係
如果設置爲True則子進程會隨父進程的退出而結束
要求必須在start()前設置
如果daemon設置成True 通常就不會使用 join()
from multiprocessing import Process
from time import sleep, ctime
def tm():
for i in range(3):
sleep(2)
print(ctime())
if __name__ == '__main__':
p = Process(target=tm)
print("Name:", p.name) # Process-1
print("PID:", p.pid) # None start()後會生成
print("is_alive:", p.is_alive()) # False start()後爲 True
print("daemon:", p.daemon) # False 默認值是False
自定義進程類
1. 創建步驟
【1】 繼承Process類
【2】 重寫 __init__ 方法添加自己的屬性,使用super()加載父類屬性
【3】 重寫run()方法
2. 使用方法
【1】 實例化對象
【2】 調用start自動執行run方法
【3】 調用join回收線程
"""
自定義進程類
"""
from multiprocessing import Process
# 自定義類
class MyProcess(Process):
def __init__(self, value):
self.value = value
super().__init__() # 加載父類init
def f1(self):
print("步驟1")
def f2(self):
print("步驟2")
def run(self):
self.f1()
self.f2()
p = MyProcess(2)
p.start() # 執行run,作爲一個子進程執行
p.join()
進程池實現
代碼示例:day8/pool.py
1. 必要性
【1】 進程的創建和銷燬過程消耗的資源較多
【2】 當任務量衆多,每個任務在很短時間內完成時,需要頻繁的創建和銷燬進程。此時對計算機壓力較大
【3】 進程池技術很好的解決了以上問題。
2. 原理
創建一定數量的進程來處理事件,事件處理完進程不退出而是繼續處理其他事件,直到所有事件全都處理完畢統一銷燬。增加進程的重複利用,降低資源消耗。
3. 進程池實現
【1】 創建進程池對象,放入適當的進程
from multiprocessing import Pool
Pool(processes)
功能: 創建進程池對象
參數: 指定進程數量,默認根據系統自動判定
【2】 將事件加入進程池隊列執行
pool.apply_async(func,args,kwds)
功能: 使用進程池執行 func事件
參數: func 事件函數
args 元組 給func按位置傳參
kwds 字典 給func按照鍵值傳參
返回值: 返回函數事件對象
【3】 關閉進程池
pool.close()
功能: 關閉進程池
【4】 回收進程池中進程
pool.join()
功能: 回收進程池中進程
"""
進程池
"""
from multiprocessing import Pool
from time import sleep
def worker(msg):
sleep(2)
print(msg)
if __name__ == '__main__':
# 創建進程池
pool = Pool(3)
for i in range(18):
msg = "Hello %d" % i
pool.apply_async(worker, (msg,))
# 結果會每2秒 執行完3個進程
pool.close()
pool.join()