multiprocessing

multiprocessing

若是你打算編寫多進程的服務程序,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實例,用start()方法啓動,這樣建立進程比fork()還要簡單。
  • join()方法能夠等待子進程結束後再繼續往下運行,一般用於進程間的同步。

Process語法結構以下:

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值;

實例1

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} 子進程已結束 

實例2

#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
相關文章
相關標籤/搜索