1. 程式人生 > >Python基礎(八)-系統程式設計之程序--multiprocessing(阻塞非阻塞)

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之後使用。

阻塞:阻塞呼叫是指呼叫結果返回之前,當前執行緒會被掛起。函式只有在得到結果之後才會返回。

非阻塞和阻塞的概念想對應,指在不能立刻得到結果之前,該函式不會阻塞當前執行緒,而會立刻返回。