多进程相关内容
多進(jìn)程相關(guān)內(nèi)容
multiprocessing模塊與process類
multiprocessing
python中的多線程無法利用多核優(yōu)勢(shì),如果想要充分地使用多核CPU的資源(os.cpu_count()查看),在python中大部分情況需要使用多進(jìn)程。Python提供了multiprocessing。
multiprocessing模塊用來開啟子進(jìn)程,并在子進(jìn)程中執(zhí)行我們定制的任務(wù)(比如函數(shù)),該模塊與多線程模塊threading的編程接口類似。
multiprocessing模塊的功能眾多:支持子進(jìn)程、通信和共享數(shù)據(jù)、執(zhí)行不同形式的同步,提供了Process、Queue、Pipe、Lock等組件。
? 需要再次強(qiáng)調(diào)的一點(diǎn)是:與線程不同,進(jìn)程沒有任何共享狀態(tài),進(jìn)程修改的數(shù)據(jù),改動(dòng)僅限于該進(jìn)程內(nèi)。
process類
參數(shù)介紹:
group參數(shù)未使用,值始終為Nonetarget表示調(diào)用對(duì)象,即子進(jìn)程要執(zhí)行的任務(wù)args表示調(diào)用對(duì)象的位置參數(shù)元組,args=(1,2,'egon',)kwargs表示調(diào)用對(duì)象的字典,kwargs={'name':'egon','age':18}name為子進(jìn)程的名稱方法介紹:
p.start():啟動(dòng)進(jìn)程,并調(diào)用該子進(jìn)程中的p.run() p.run():進(jìn)程啟動(dòng)時(shí)運(yùn)行的方法,正是它去調(diào)用target指定的函數(shù),我們自定義類的類中一定要實(shí)現(xiàn)該方法 p.terminate():強(qiáng)制終止進(jìn)程p,不會(huì)進(jìn)行任何清理操作,如果p創(chuàng)建了子進(jìn)程,該子進(jìn)程就成了僵尸進(jìn)程,使用該方法需要特別小心這種情況。如果p還保存了一個(gè)鎖那么也將不會(huì)被釋放,進(jìn)而導(dǎo)致死鎖p.is_alive():如果p仍然運(yùn)行,返回Truep.join([timeout]):主線程等待p終止(強(qiáng)調(diào):是主線程處于等的狀態(tài),而p是處于運(yùn)行的狀態(tài))。timeout是可選的超時(shí)時(shí)間,需要強(qiáng)調(diào)的是,p.join只能join住start開啟的進(jìn)程,而不能join住run開啟的進(jìn)程屬性介紹:
p.daemon:默認(rèn)值為False,如果設(shè)為True,代表p為后臺(tái)運(yùn)行的守護(hù)進(jìn)程,當(dāng)p的父進(jìn)程終止時(shí),p也隨之終止,并且設(shè)定為True后,p不能創(chuàng)建自己的新進(jìn)程,必須在p.start()之前設(shè)置p.name:進(jìn)程的名稱p.pid:進(jìn)程的pidp.exitcode:進(jìn)程在運(yùn)行時(shí)為None、如果為–N,表示被信號(hào)N結(jié)束(了解即可)p.authkey:進(jìn)程的身份驗(yàn)證鍵,默認(rèn)是由os.urandom()隨機(jī)生成的32字符的字符串。這個(gè)鍵的用途是為涉及網(wǎng)絡(luò)連接的底層進(jìn)程間通信提供安全性,這類連接只有在具有相同的身份驗(yàn)證鍵時(shí)才能成功(了解即可)創(chuàng)建子進(jìn)程的兩種方式
注意:在windows中Process()必須放到# if name == 'main':下
第一種方式:
from multiprocessing import Process import time def task(name):print(f"{name} is running")time.sleep(3)print(f"{name} is gone") if __name__ == '__main__':p = Process(target = task,args=('黑哥',)) # 創(chuàng)建一個(gè)進(jìn)程對(duì)象# p = Process(target=task,kwargs={'name':'黑哥'}) 兩種傳參方式p.start() # 只是向操作系統(tǒng)發(fā)出一個(gè)開辟子進(jìn)程的信號(hào),然后就執(zhí)行下一行了.# 這個(gè)信號(hào)操作系統(tǒng)接收到之后,會(huì)從內(nèi)存中開辟一個(gè)子進(jìn)程空間,然后在將主進(jìn)程所有數(shù)據(jù)copy加載到子進(jìn)程,然后在調(diào)用cpu去執(zhí)行.# 開辟子進(jìn)程開銷是很大的.print('==主')# 所以永遠(yuǎn)會(huì)先執(zhí)行主進(jìn)程的代碼. # 結(jié)果: ==主 黑哥 is running 黑哥 is gone第二種方式:
from multiuprocessing import Process import timeclass MyProcess(Process):def __init__(self,name):super().__init__()self.name = namedef run(self): # 必須定義一個(gè)run方法print(f"{self.name} is runing")time.sleep(2)print(f"{self.name} is gone") if __name__ == "__main__":p = MyProcess('黑哥')p.start()print('==主') # 結(jié)果: ==主 黑哥 is running 黑哥 is gone簡(jiǎn)單應(yīng)用:
from multiprocessing import Process import time def task(name):print(f"{name} is running")time.sleep(2)print(f"{name} is gone")def task1(name):print(f"{name} is running")time.sleep(2)print(f"{name} is gone") def task2(name):print(f"{name} is running")time.sleep(2)print(f"{name} is gone") if __name__ == '__main__':p1 = Process(target=task,args=('黑哥',))p2 = Process(target=task,args=('李業(yè)',))start_time = time.time() # task('黑哥') # task1('李業(yè)') # task2('海狗') # print(f"結(jié)束時(shí)間{time.time() - start_time}")p1.start() # 使用多進(jìn)程優(yōu)化代碼運(yùn)行時(shí)間p2.start() task('海狗')print(f"結(jié)束時(shí)間{time.time()-start_time}")進(jìn)程pid
如何獲取內(nèi)存中的所有進(jìn)程?
- 命令行獲取所有的進(jìn)程的pid tasklist
代碼級(jí)別如果獲取一個(gè)進(jìn)程pid
import os print(os.getpid())如何獲取父進(jìn)程(主進(jìn)程)的pid?
import osimport time print(f'子進(jìn)程:{os.getpid()}') print(f'主(父)進(jìn)程:{os.getppid()}')驗(yàn)證進(jìn)程之間的空間隔離
在同一進(jìn)程中:
x = 1000 def task():global xx = 2 task() print(x) # 結(jié)果: 2在不同進(jìn)程中:
from multiprocessing import Process import time x = 1000 def task():global xx = 2if __name__ == '__main__':p = Process(target=task)p.start()time.sleep(3)print(x) # 結(jié)果: 1000進(jìn)程對(duì)象的join方法
join讓主進(jìn)程等待子進(jìn)程結(jié)束之后,在執(zhí)行主進(jìn)程.
from multiprocessing import Process import time def task(name):print(f"{name} is running")time.sleep(2)print(f"{name} is gone")if __name__ == '__main__':p = Process(target=task,args=('黑哥',))p.start()p.join()print("==主")多個(gè)子進(jìn)程使用join
from multiprocessing import Process import timedef task(name,sec):print(f"{name} is running")time.sleep(sec)print(f"{name} is gone")if __name__ == '__main__':start_time = time.time()p1 = Process(target=task,args=('黑哥',1))p2 = Process(target=task,args=('李業(yè)',2))p3 = Process(target=task,args=('海狗',3))p1.start()p2.start()p3.start()p1.join()p2.join()p3.join()print(f"==主{time.time()-start_time}") # 結(jié)果: 李業(yè) is running 黑哥 is running 海狗 is running 黑哥 is gone 李業(yè) is gone 海狗 is gone ==主3.6357808113098145 from multiprocessing import Process import time def task(name,sec):print(f'{name} is running')time.sleep(sec)print(f"{name} is gone") if __name__ == '__main__':start_time = time.time()p1 = Process(target=task,args=('黑哥',3))p2 = Process(target=task,args=('李業(yè)',2))p3 = Process(target=task,args=('海狗',4))p1.start()p2.start()p3.start()p1.join()print(f"==主1:{time.time()-start_time}")p2.join()print(f"==主2:{time.time()-start_time}")p3.join()print(f"==主3:{time.time()-start_time}") # 結(jié)果: 黑哥 is running 海狗 is running 李業(yè) is running 李業(yè) is gone 黑哥 is gone ==主1:3.741270065307617 ==主2:3.741270065307617 海狗 is gone ==主3:4.746762990951538相關(guān)面試題:
# 優(yōu)化下面的代碼: from multiprocessing import Process import timedef task(sec):print(f'is running')time.sleep(sec)print(f' is gone')if __name__ == '__main__':start_time = time.time()p1 = Process(target=task,args=(1,))p2 = Process(target=task,args=(2,))p3 = Process(target=task,args=(3,))p1.start()p2.start()p3.start()# join 只針對(duì)主進(jìn)程,如果join下面多次join 他是不阻塞的.p1.join()p2.join()p3.join()# 正確解法: from multiprocessing import Process import timedef task(sec):print(f"is running")time.sleep(sec)print(f"is gone")if __name__ == '__main__':p1 = Process(target=task,args=('常鑫',3))p2 = Process(target=task,args=('立業(yè)',2))p3 = Process(target=task,args=('還夠',4))start_time = time.time()p1.start()p2.start()p3.start()lst = []for i in range(1,4):p = Process(target=task,args = (i,))p.start()lst.append(p)for i in lst:i.join()print(f"{i}", f'{time.time() - start_time}')進(jìn)程對(duì)象的其他屬性
from multiprocessing import Process import timedef task(name):print(f"{name} is running")time.sleep(2)print(f"{name} is gone")if __name__ == '__main__':# p = Process(target=task,args=('黑哥',))p = Process(target=task,args=('黑哥',),name='alex')p.start()time.sleep(1)p.terminate() # 殺死子進(jìn)程p.join()time.sleep(0.5)print(p.is_alive()) # 判斷進(jìn)程是否存在print(p.name)p.name = 'sb' # 給子進(jìn)程起名字print(p.name)print('==主開始')守護(hù)進(jìn)程
子進(jìn)程守護(hù)著主進(jìn)程,只要主進(jìn)程結(jié)束,子進(jìn)程跟著就結(jié)束,
主進(jìn)程創(chuàng)建守護(hù)進(jìn)程
其一:守護(hù)進(jìn)程會(huì)在主進(jìn)程代碼執(zhí)行結(jié)束后就終止
其二:守護(hù)進(jìn)程內(nèi)無法再開啟子進(jìn)程,否則拋出異常:AssertionError: daemonic processes are not allowed to have children
注意:進(jìn)程之間是互相獨(dú)立的,主進(jìn)程代碼運(yùn)行結(jié)束,守護(hù)進(jìn)程隨即終止
import time def task(name):print(f"{name} is running")time.sleep(2)print(f"{name} is gone")if __name__ == '__main__':p = Process(target=task,args=('黑哥',))p.daemon = True # 一定要在子進(jìn)程開啟之前設(shè)置p.start()time.sleep(1)print('==主') # 結(jié)果: 黑哥 is running ==主轉(zhuǎn)載于:https://www.cnblogs.com/lifangzheng/p/11384000.html
總結(jié)
- 上一篇: 《卧龙》捏脸有黑人引热议 网友:黑人也要
- 下一篇: 如何读取xlsx表格内容