什么是進程方仿?
- 一個程序運行起來后荣茫,代碼+用到的資源 稱之為進程丧慈,它是操作系統(tǒng)分配資源的基本單元馍迄。
進程的創(chuàng)建-multiprocessing
- multiprocessing模塊就是跨平臺版本的多進程模塊艳吠,提供了一個Process類來代表一個進程對象麦备,這個對象可以理解為是一個獨立的進程,可以執(zhí)行另外的事情
from multiprocessing import Process
import time
def run_proc():
"""子進程要執(zhí)行的代碼"""
while True:
print("2")
time.sleep(1)
if __name__ == '__main__':
p = Process(target=run_proc)
p.start()
while True:
print("1")
time.sleep(1)
Process參數(shù)如下:
Process(group, target, name, args , kwargs)
- target:如果傳遞了函數(shù)的引用昭娩,可以任務(wù)這個子進程就執(zhí)行這里的代碼
- args:給target指定的函數(shù)傳遞的參數(shù)凛篙,以元組的方式傳遞
- kwargs:給target指定的函數(shù)傳遞命名參數(shù)
- name:給進程設(shè)定一個名字,可以不設(shè)定
- group:指定進程組题禀,大多數(shù)情況下用不到
Process創(chuàng)建的實例對象的常用方法:
- strart(): 啟動子進程實例(創(chuàng)建子進程)
- is_alive(): 判斷進程子進程是否還在活著
- join([timeout]): 是否等待子進程執(zhí)行結(jié)束鞋诗,或等待多少秒
- terminate(): 不管任務(wù)是否完成,立即終止子進程
Process創(chuàng)建的實例對象的常用屬性:
- name: 當(dāng)前進程的別名迈嘹,默認(rèn)為Process-N,N為1開始遞增的整數(shù)
- pid: 當(dāng)前進程的pid(進程號)
進程間通信-Queue
- Queue的使用 可以使用multiprocessing模塊的Queue實現(xiàn)多進程之間的數(shù)據(jù)傳遞削彬,Queue本身是一個消息列隊程序全庸,以下小實例來演示一下Queue的工作原理:
#coding=utf-8
from multiprocessing import Queue
q=Queue(3) #初始化一個Queue對象,最多可接收三條put消息
q.put("消息1")
q.put("消息2")
print(q.full()) #False
q.put("消息3")
print(q.full()) #True
#因為消息列隊已滿下面的try都會拋出異常融痛,第一個try會等待2秒后再拋出異常壶笼,第二個Try會立刻拋出異常
try:
q.put("消息4",True,2)
except:
print("消息列隊已滿,現(xiàn)有消息數(shù)量:%s"%q.qsize())
try:
q.put_nowait("消息4")
except:
print("消息列隊已滿雁刷,現(xiàn)有消息數(shù)量:%s"%q.qsize())
#推薦的方式覆劈,先判斷消息列隊是否已滿,再寫入
if not q.full():
q.put_nowait("消息4")
#讀取消息時沛励,先判斷消息列隊是否為空责语,再讀取
if not q.empty():
for i in range(q.qsize()):
print(q.get_nowait())
- Queue.qsize():返回當(dāng)前隊列包含的消息數(shù)量;
- Queue.empty():如果隊列為空目派,返回True坤候,反之False ;
- Queue.full():如果隊列滿了企蹭,返回True,反之False白筹;
- Queue.get(block, timeout):獲取隊列中的一條消息,然后將其從列隊中移除谅摄,block默認(rèn)值為True徒河;
進程池Pool
- 當(dāng)需要創(chuàng)建的子進程數(shù)量不多時,可以直接利用multiprocessing中的Process動態(tài)成生多個進程送漠,但如果是上百甚至上千個目標(biāo)顽照,手動的去創(chuàng)建進程的工作量巨大,此時就可以用到multiprocessing模塊提供的Pool方法螺男。
- 初始化Pool時棒厘,可以指定一個最大進程數(shù),當(dāng)有新的請求提交到Pool中時下隧,如果池還沒有滿奢人,那么就會創(chuàng)建一個新的進程用來執(zhí)行該請求;但如果池中的進程數(shù)已經(jīng)達到指定的最大值淆院,那么該請求就會等待何乎,直到池中有進程結(jié)束,才會用之前的進程來執(zhí)行新的任務(wù)土辩,請看下面的實例:
# -*- coding:utf-8 -*-
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))
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(進程池)不再接收新任務(wù)
po.join() # 等待po(進程池)中所有子進程執(zhí)行完成各墨,必須放在close語句之后
print("-----end-----")