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),該類(lèi)可用來(lái)在 Windows 平臺(tái)上創(chuàng)建新進(jìn)程。和使用 Thread 類(lèi)創(chuàng)建多線程方法類(lèi)似,使用 Process 類(lèi)創(chuàng)建多進(jìn)程也有以下 2 種方式:
直接創(chuàng)建 Process 類(lèi)的實(shí)例對(duì)象,由此就可以創(chuàng)建一個(gè)新的進(jìn)程;
通過(guò)繼承 Process 類(lèi)的子類(lèi),創(chuàng)建實(shí)例對(duì)象,也可以創(chuàng)建新的進(jìn)程。注意,繼承 Process 類(lèi)的子類(lèi)需重寫(xiě)父類(lèi)的 run() 方法。
不僅如此,Process 類(lèi)中也提供了一些常用的屬性和方法,如表 1 所示。
屬性名或方法名 | 功能 |
---|---|
run() | 第 2 種創(chuàng)建進(jìn)程的方式需要用到,繼承類(lèi)中需要對(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 類(lèi) join() 方法的用法類(lèi)似,其功能是在多進(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)程的名稱(chēng)。 |
daemon | 和守護(hù)線程類(lèi)似,通過(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)常用屬性和方法
接下來(lái)將一一對(duì)創(chuàng)建進(jìn)程的 2 種方法做詳細(xì)的講解。
通過(guò)Process類(lèi)創(chuàng)建進(jìn)程
和使用 thread 類(lèi)創(chuàng)建子線程的方式非常類(lèi)似,使用 Process 類(lèi)創(chuàng)建實(shí)例化對(duì)象,其本質(zhì)是調(diào)用該類(lèi)的構(gòu)造方法創(chuàng)建新進(jìn)程。Process 類(lèi)的構(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è)置名稱(chēng);
- args:為 target 參數(shù)指定的參數(shù)傳遞非關(guān)鍵字參數(shù);
- kwargs:為 target 參數(shù)指定的參數(shù)傳遞關(guān)鍵字參數(shù)。
下面程序演示了如何用 Process 類(lèi)創(chuàng)建新進(jìn)程。
from multiprocessing import Process import os print("當(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)程12980
http://jb51.net/shell/ --當(dāng)前進(jìn)程12980
http://jb51.net/java/ --當(dāng)前進(jìn)程12980
當(dāng)前進(jìn)程ID: 12860
my_process進(jìn)程
http://jb51.net/python/ --當(dāng)前進(jìn)程12860
http://jb51.net/shell/ --當(dāng)前進(jìn)程12860
http://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繼承類(lèi)創(chuàng)建進(jìn)程
和使用 thread 子類(lèi)創(chuàng)建線程的方式類(lèi)似,除了直接使用 Process 類(lèi)創(chuàng)建進(jìn)程,還可以通過(guò)創(chuàng)建 Process 的子類(lèi)來(lái)創(chuàng)建進(jìn)程。
需要注意的是,在創(chuàng)建 Process 的子類(lèi)時(shí),需在子類(lèi)內(nèi)容重寫(xiě) run() 方法。實(shí)際上,該方法所起到的作用,就如同第一種創(chuàng)建方式中 target 參數(shù)執(zhí)行的函數(shù)。
另外,通過(guò) Process 子類(lèi)創(chuàng)建進(jìn)程,和使用 Process 類(lèi)一樣,先創(chuàng)建該類(lèi)的實(shí)例對(duì)象,然后調(diào)用 start() 方法啟動(dòng)該進(jìn)程。下面程序演示如何通過(guò) Process 子類(lèi)創(chuàng)建一個(gè)進(jìn)程。
from multiprocessing import Process import os print("當(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)程類(lèi) 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)程22240
http://jb51.net/shell/ --當(dāng)前進(jìn)程22240
http://jb51.net/java/ --當(dāng)前進(jìn)程22240
當(dāng)前進(jìn)程ID: 18848
my_process進(jìn)程
http://jb51.net/python/ --當(dāng)前進(jìn)程18848
http://jb51.net/shell/ --當(dāng)前進(jìn)程18848
http://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)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python3中類(lèi)的繼承以及self和super的區(qū)別詳解
今天小編就為大家分享一篇python3中類(lèi)的繼承以及self和super的區(qū)別詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06如何從Python字符串中刪除最后一個(gè)分號(hào)或者逗號(hào)
這篇文章主要介紹了從?Python?中的字符串中刪除最后一個(gè)分號(hào)或者逗號(hào)的兩種方法,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-04-04python之pexpect實(shí)現(xiàn)自動(dòng)交互的例子
今天小編就為大家分享一篇python之pexpect實(shí)現(xiàn)自動(dòng)交互的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07Python實(shí)現(xiàn)Word和TXT文件格式之間的相互轉(zhuǎn)換
Word文檔(.doc或.docx)和純文本文件(.txt)是兩種常用的文件格式,本文將詳細(xì)介紹如何使用Python實(shí)現(xiàn)Word和TXT文件格式之間的相互轉(zhuǎn)換,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下2024-07-07python實(shí)現(xiàn)的一個(gè)火車(chē)票轉(zhuǎn)讓信息采集器
這篇文章主要介紹了python實(shí)現(xiàn)的一個(gè)火車(chē)票轉(zhuǎn)讓信息采集器,采集信息來(lái)源是58同程或者趕集網(wǎng),需要的朋友可以參考下2014-07-07Flask SocketIO實(shí)現(xiàn)動(dòng)態(tài)繪圖的示例詳解
Flask-SocketIO 是基于 Flask 的一個(gè)擴(kuò)展,用于簡(jiǎn)化在 Flask 應(yīng)用中集成 WebSocket 功能,本文主要介紹了Flask SocketIO如何實(shí)現(xiàn)動(dòng)態(tài)繪圖,需要的可以參考下2023-11-11Python爬蟲(chóng)爬取微博熱搜保存為 Markdown 文件的源碼
這篇文章主要介紹了Python爬蟲(chóng)爬取微博熱搜保存為 Markdown 文件,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02Python之freegames?零代碼的22個(gè)小游戲集合
這篇文章主要介紹了,Python之freegames?零代碼的22個(gè)小游戲集合,文章內(nèi)容詳細(xì),簡(jiǎn)單易懂,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2023-01-01