若是你打算編寫多進程的服務程序,Unix/Linux無疑是正確的選擇。因爲Windows沒有fork調用,難道在Windows上沒法用Python編寫多進程的程序?python
因爲Python是跨平臺的,天然也應該提供一個跨平臺的多進程支持。multiprocessing模塊就是跨平臺版本的多進程模塊。shell
multiprocessing模塊提供了一個Process類來表明一個進程對象,下面的例子演示了啓動一個子進程並等待其結束:函數
#coding=utf-8 from multiprocessing import Process import os # 子進程要執行的代碼 def run_proc(name): print('子進程運行中,name= %s ,pid=%d...' % (name, os.getpid())) if __name__=='__main__': print('父進程 %d.' % os.getpid()) p = Process(target=run_proc, args=('test',)) print('子進程將要執行') p.start() p.join() print('子進程已結束')
運行結果: spa
Process([group [, target [, name [, args [, kwargs]]]]])code
target:表示這個進程實例所調用對象;對象
args:表示調用對象的位置參數元組;blog
kwargs:表示調用對象的關鍵字參數字典;進程
name:爲當前進程實例的別名;ip
group:大多數狀況下用不到;utf-8
Process類經常使用方法:
is_alive():判斷進程實例是否還在執行;
join([timeout]):是否等待進程實例執行結束,或等待多少秒;
start():啓動進程實例(建立子進程);
run():若是沒有給定target參數,對這個對象調用start()方法時,就將執行對象中的run()方法;
terminate():無論任務是否完成,當即終止;
Process類經常使用屬性:
name:當前進程實例別名,默認爲Process-N,N爲從1開始遞增的整數;
pid:當前進程實例的PID值;
from multiprocessing import Process import os from time import sleep # 子進程要執行的代碼 def run_proc(name, age, **kwargs): for i in range(10): print('子進程運行中,name= %s,age=%d ,pid=%d...' % (name, age,os.getpid())) print(kwargs) sleep(0.5) if __name__=='__main__': print('父進程 %d.' % os.getpid()) p = Process(target=run_proc, args=('test',18), kwargs={"m":20}) print('子進程將要執行') p.start() sleep(1) p.terminate() p.join() print('子進程已結束')
運行結果:
父進程 21378. 子進程將要執行 子進程運行中,name= test,age=18 ,pid=21379... {'m': 20} 子進程運行中,name= test,age=18 ,pid=21379... {'m': 20} 子進程已結束
#coding=utf-8 from multiprocessing import Process import time import os #兩個子進程將會調用的兩個方法 def worker_1(interval): print("worker_1,父進程(%s),當前進程(%s)"%(os.getppid(),os.getpid())) t_start = time.time() time.sleep(interval) #程序將會被掛起interval秒 t_end = time.time() print("worker_1,執行時間爲'%0.2f'秒"%(t_end - t_start)) def worker_2(interval): print("worker_2,父進程(%s),當前進程(%s)"%(os.getppid(),os.getpid())) t_start = time.time() time.sleep(interval) t_end = time.time() print("worker_2,執行時間爲'%0.2f'秒"%(t_end - t_start)) #輸出當前程序的ID print("進程ID:%s"%os.getpid()) #建立兩個進程對象,target指向這個進程對象要執行的對象名稱, #args後面的元組中,是要傳遞給worker_1方法的參數, #由於worker_1方法就一個interval參數,這裏傳遞一個整數2給它, #若是不指定name參數,默認的進程對象名稱爲Process-N,N爲一個遞增的整數 p1=Process(target=worker_1,args=(2,)) p2=Process(target=worker_2,name="dongGe",args=(1,)) #使用"進程對象名稱.start()"來建立並執行一個子進程, #這兩個進程對象在start後,就會分別去執行worker_1和worker_2方法中的內容 p1.start() p2.start() #同時父進程仍然往下執行,若是p2進程還在執行,將會返回True print("p2.is_alive=%s"%p2.is_alive()) #輸出p1和p2進程的別名和pid print("p1.name=%s"%p1.name) print("p1.pid=%s"%p1.pid) print("p2.name=%s"%p2.name) print("p2.pid=%s"%p2.pid) #join括號中不攜帶參數,表示父進程在這個位置要等待p1進程執行完成後, #再繼續執行下面的語句,通常用於進程間的數據同步,若是不寫這一句, #下面的is_alive判斷將會是True,在shell(cmd)裏面調用這個程序時 #能夠完整的看到這個過程,你們能夠嘗試着將下面的這條語句改爲p1.join(1), #由於p2須要2秒以上纔可能執行完成,父進程等待1秒極可能不能讓p1徹底執行完成, #因此下面的print會輸出True,即p1仍然在執行 p1.join() print("p1.is_alive=%s"%p1.is_alive())
執行結果:
進程ID:19866 p2.is_alive=True p1.name=Process-1 p1.pid=19867 p2.name=dongGe p2.pid=19868 worker_1,父進程(19866),當前進程(19867) worker_2,父進程(19866),當前進程(19868) worker_2,執行時間爲'1.00'秒 worker_1,執行時間爲'2.00'秒 p1.is_alive=False