Python基礎(八)-系統程式設計之程序--multiprocessing(阻塞非阻塞)
程序擁有自己獨立的堆和棧,既不共享堆,亦不共享棧,程序由作業系統排程。
執行緒擁有自己獨立的棧和共享的堆,共享堆,不共享棧,執行緒亦由作業系統排程(標準執行緒是的)。
協程和執行緒一樣共享堆,不共享棧,協程由程式設計師在協程的程式碼裡顯示排程
multiprocessing模組提供了process類來代表一個程序物件。 語法結構: process([group[,target[,name[,args[,kwargs]]]]]) target:表示程序例項所呼叫的物件 args表示呼叫物件的位置引數元組 kwargs表示呼叫物件的關鍵字引數字典 name:為當前程序例項的別名
建立子程序時,只需要傳入一個執行函式和函式的引數,建立一個Process例項,用start方法啟動,
用join()方法可一個等待子程序結束後再繼續往下執行。一般用於程序間的同步
process類常用方法:
is_alive().判斷程序例項是否還在執行
join([timeout]):是否等待程序例項執行結束,或等待多少秒
start()啟動程序例項,即建立子程序
run()如果沒有給定target引數,對物件呼叫start()方法時,就將執行物件中的run方法;
terminate()不管任務是否完成,立即終止。
程序池:
當建立的子程序數量不多時,可以直接利用process動態生成多個程序,當需要建立的程序數非常大的時候,需要用到程序池,即multiprocessing模組提供的Pool方法。
初始化pool時,可以指定一個最大程序數。有新的請求提交到pool中時,如果池還沒滿,就會建立一個新的程序來執行該請求,如果翅中的程序數已經達到指定的最大值,那麼該請求就會等待,直到池中有程序結束,才會建立新的程序來執行。
from multiprocessing import Pool
import os,time,random
def worker(msg):
t_start = time.time()
print("%s開始執行,程序號為%d"%(msg,os.getpid()))
#random.random()隨機生成0~1之間的浮點數
time.sleep(random.random()*2 )
t_stop = time.time()
print(msg,"執行完畢,耗時%0.2f"%(t_stop-t_start))
po=Pool(3) #定義一個程序池,最大程序數3
for i in range(0,10):
#Pool.apply_async(要呼叫的目標,(傳遞給目標的引數元祖,))
#每次迴圈將會用空閒出來的子程序去呼叫目標
po.apply_async(worker,(i,))
print("----start----")
po.close() #關閉程序池,關閉後po不再接收新的請求
po.join() #等待po中所有子程序執行完成,必須放在close語句之後
print("-----end-----")
apply_async(func[,args[,kwds]]):使用非阻塞方式呼叫func(並行執行:同時執行兩個或更多個處理,並行處理可同時工作於同一程式的不同方面。並行處理的主要目的是節省大型和複雜問題的解決時間)。阻塞方式:必須等上一個程序退出才能執行下一個程序。
args為傳遞給func的引數列表,kwds為傳遞給func的關鍵字引數列表。
apply(func[,args[,kwds]]):使用非阻塞方式呼叫func
close()關閉POOL,使其不再接受新的任務。
terminate():不管任務是否完成,立即終止
join():主程序阻塞,等待子程序的退出,必須在close或terminate之後使用。
阻塞:阻塞呼叫是指呼叫結果返回之前,當前執行緒會被掛起。函式只有在得到結果之後才會返回。
非阻塞和阻塞的概念想對應,指在不能立刻得到結果之前,該函式不會阻塞當前執行緒,而會立刻返回。