Python Process創(chuàng)建進(jìn)程的2種方法詳解
前面介紹了使用 os.fork() 函數(shù)實(shí)現(xiàn)多進(jìn)程編程,該方法最明顯的缺陷就是不適用于 Windows 系統(tǒng)。本節(jié)將介紹一種支持 Python 在 Windows 平臺(tái)上創(chuàng)建新進(jìn)程的方法。
Python multiprocessing 模塊提供了 Process 類,該類可用來(lái)在 Windows 平臺(tái)上創(chuàng)建新進(jìn)程。和使用 Thread 類創(chuàng)建多線程方法類似,使用 Process 類創(chuàng)建多進(jìn)程也有以下 2 種方式:
直接創(chuàng)建 Process 類的實(shí)例對(duì)象,由此就可以創(chuàng)建一個(gè)新的進(jìn)程;
通過(guò)繼承 Process 類的子類,創(chuàng)建實(shí)例對(duì)象,也可以創(chuàng)建新的進(jìn)程。注意,繼承 Process 類的子類需重寫(xiě)父類的 run() 方法。
不僅如此,Process 類中也提供了一些常用的屬性和方法,如表 1 所示。
屬性名或方法名 功能 run() 第 2 種創(chuàng)建進(jìn)程的方式需要用到,繼承類中需要對(duì)方法進(jìn)行重寫(xiě),該方法中包含的是新進(jìn)程要執(zhí)行的代碼。 start() 和啟動(dòng)子線程一樣,新創(chuàng)建的進(jìn)程也需要手動(dòng)啟動(dòng),該方法的功能就是啟動(dòng)新創(chuàng)建的線程。 join([timeout]) 和 thread 類 join() 方法的用法類似,其功能是在多進(jìn)程執(zhí)行過(guò)程,其他進(jìn)程必須等到調(diào)用 join() 方法的進(jìn)程執(zhí)行完畢(或者執(zhí)行規(guī)定的 timeout 時(shí)間)后,才能繼續(xù)執(zhí)行; is_alive() 判斷當(dāng)前進(jìn)程是否還活著。 terminate() 中斷該進(jìn)程。 name屬性 可以為該進(jìn)程重命名,也可以獲得該進(jìn)程的名稱。 daemon 和守護(hù)線程類似,通過(guò)設(shè)置該屬性為 True,可將新建進(jìn)程設(shè)置為“守護(hù)進(jìn)程”。 pid 返回進(jìn)程的 ID 號(hào)。大多數(shù)操作系統(tǒng)都會(huì)為每個(gè)進(jìn)程配備唯一的 ID 號(hào)。
表 1 Python Process類常用屬性和方法
接下來(lái)將一一對(duì)創(chuàng)建進(jìn)程的 2 種方法做詳細(xì)的講解。
通過(guò)Process類創(chuàng)建進(jìn)程和使用 thread 類創(chuàng)建子線程的方式非常類似,使用 Process 類創(chuàng)建實(shí)例化對(duì)象,其本質(zhì)是調(diào)用該類的構(gòu)造方法創(chuàng)建新進(jìn)程。Process 類的構(gòu)造方法格式如下:
def __init__(self,group=None,target=None,name=None,args=(),kwargs={})
其中,各個(gè)參數(shù)的含義為:
group:該參數(shù)未進(jìn)行實(shí)現(xiàn),不需要傳參; target:為新建進(jìn)程指定執(zhí)行任務(wù),也就是指定一個(gè)函數(shù); name:為新建進(jìn)程設(shè)置名稱; args:為 target 參數(shù)指定的參數(shù)傳遞非關(guān)鍵字參數(shù); kwargs:為 target 參數(shù)指定的參數(shù)傳遞關(guān)鍵字參數(shù)。下面程序演示了如何用 Process 類創(chuàng)建新進(jìn)程。
from multiprocessing import Processimport osprint('當(dāng)前進(jìn)程ID:',os.getpid())# 定義一個(gè)函數(shù),準(zhǔn)備作為新進(jìn)程的 target 參數(shù)def action(name,*add): print(name) for arc in add: print('%s --當(dāng)前進(jìn)程%d' % (arc,os.getpid()))if __name__==’__main__’: #定義為進(jìn)程方法傳入的參數(shù) my_tuple = ('http://jb51.net/python/', 'http://jb51.net/shell/', 'http://jb51.net/java/') #創(chuàng)建子進(jìn)程,執(zhí)行 action() 函數(shù) my_process = Process(target = action, args = ('my_process進(jìn)程',*my_tuple)) #啟動(dòng)子進(jìn)程 my_process.start() #主進(jìn)程執(zhí)行該函數(shù) action('主進(jìn)程',*my_tuple)
程序執(zhí)行結(jié)果為:當(dāng)前進(jìn)程ID: 12980主進(jìn)程http://jb51.net/python/ --當(dāng)前進(jìn)程12980http://jb51.net/shell/ --當(dāng)前進(jìn)程12980http://jb51.net/java/ --當(dāng)前進(jìn)程12980當(dāng)前進(jìn)程ID: 12860my_process進(jìn)程http://jb51.net/python/ --當(dāng)前進(jìn)程12860http://jb51.net/shell/ --當(dāng)前進(jìn)程12860http://jb51.net/java/ --當(dāng)前進(jìn)程12860
需要說(shuō)明的是,通過(guò) multiprocessing.Process 來(lái)創(chuàng)建并啟動(dòng)進(jìn)程時(shí),程序必須先判斷 if __name__==’__main__’:,否則運(yùn)行該程序會(huì)引發(fā)異常。
此程序中有 2 個(gè)進(jìn)程,分別為主進(jìn)程和我們創(chuàng)建的新進(jìn)程,主進(jìn)程會(huì)執(zhí)行整個(gè)程序,而子進(jìn)程不會(huì)執(zhí)行 if __name__ == ’__main__’ 中包含的程序,而是先執(zhí)行此判斷語(yǔ)句之外的所有可執(zhí)行程序,然后再執(zhí)行我們分配讓它的任務(wù)(也就是通過(guò) target 參數(shù)指定的函數(shù))。
通過(guò)Process繼承類創(chuàng)建進(jìn)程和使用 thread 子類創(chuàng)建線程的方式類似,除了直接使用 Process 類創(chuàng)建進(jìn)程,還可以通過(guò)創(chuàng)建 Process 的子類來(lái)創(chuàng)建進(jìn)程。
需要注意的是,在創(chuàng)建 Process 的子類時(shí),需在子類內(nèi)容重寫(xiě) run() 方法。實(shí)際上,該方法所起到的作用,就如同第一種創(chuàng)建方式中 target 參數(shù)執(zhí)行的函數(shù)。
另外,通過(guò) Process 子類創(chuàng)建進(jìn)程,和使用 Process 類一樣,先創(chuàng)建該類的實(shí)例對(duì)象,然后調(diào)用 start() 方法啟動(dòng)該進(jìn)程。下面程序演示如何通過(guò) Process 子類創(chuàng)建一個(gè)進(jìn)程。
from multiprocessing import Processimport osprint('當(dāng)前進(jìn)程ID:',os.getpid())# 定義一個(gè)函數(shù),供主進(jìn)程調(diào)用def action(name,*add): print(name) for arc in add: print('%s --當(dāng)前進(jìn)程%d' % (arc,os.getpid()))#自定義一個(gè)進(jìn)程類class My_Process(Process): def __init__(self,name,*add): super().__init__() self.name = name self.add = add def run(self): print(self.name) for arc in self.add: print('%s --當(dāng)前進(jìn)程%d' % (arc,os.getpid()))if __name__==’__main__’: #定義為進(jìn)程方法傳入的參數(shù) my_tuple = ('http://jb51.net/python/', 'http://jb51.net/shell/', 'http://jb51.net/java/') my_process = My_Process('my_process進(jìn)程',*my_tuple) #啟動(dòng)子進(jìn)程 my_process.start() #主進(jìn)程執(zhí)行該函數(shù) action('主進(jìn)程',*my_tuple)
程序執(zhí)行結(jié)果為:當(dāng)前進(jìn)程ID: 22240主進(jìn)程http://jb51.net/python/ --當(dāng)前進(jìn)程22240http://jb51.net/shell/ --當(dāng)前進(jìn)程22240http://jb51.net/java/ --當(dāng)前進(jìn)程22240當(dāng)前進(jìn)程ID: 18848my_process進(jìn)程http://jb51.net/python/ --當(dāng)前進(jìn)程18848http://jb51.net/shell/ --當(dāng)前進(jìn)程18848http://jb51.net/java/ --當(dāng)前進(jìn)程18848
顯然,該程序的運(yùn)行結(jié)果與上一個(gè)程序的運(yùn)行結(jié)果大致相同,它們只是創(chuàng)建進(jìn)程的方式略有不同而已。推薦讀者使用第一種方式來(lái)創(chuàng)建進(jìn)程,因?yàn)檫@種方式不僅編程簡(jiǎn)單,而且進(jìn)程直接包裝 target 函數(shù),具有更清晰的邏輯結(jié)構(gòu)。
到此這篇關(guān)于Python Process創(chuàng)建進(jìn)程的2種方法詳解的文章就介紹到這了,更多相關(guān)Python Process創(chuàng)建進(jìn)程內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. IntelliJ IDEA刪除類的方法步驟2. JSP中Servlet的Request與Response的用法與區(qū)別3. Struts2獲取參數(shù)的三種方法總結(jié)4. vue使用moment如何將時(shí)間戳轉(zhuǎn)為標(biāo)準(zhǔn)日期時(shí)間格式5. Android 實(shí)現(xiàn)徹底退出自己APP 并殺掉所有相關(guān)的進(jìn)程6. IntelliJ IDEA導(dǎo)入jar包的方法7. js select支持手動(dòng)輸入功能實(shí)現(xiàn)代碼8. vue cli4下環(huán)境變量和模式示例詳解9. Django視圖類型總結(jié)10. Xml簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
