第九章併發編程 同一個程式執行多次是多個進程 9.1 開啟子進程的兩種方式 服務端目標: 1、不間斷地提供服務 2、服務端要支持高併發+高性能 一個進程在運行過程中開啟了子進程(如nginx開啟多進程,os.fork,subprocess.Popen等) 父進程發起請求,操作系統創建子進程 方式一: ...
第九章併發編程
同一個程式執行多次是多個進程
import time import os print('爹是:',os.getppid()) #父進程PID,(pycharm) print('me是: ',os.getpid()) #3748 14648 time.sleep(500)
9.1 開啟子進程的兩種方式
服務端目標: 1、不間斷地提供服務 2、服務端要支持高併發+高性能
一個進程在運行過程中開啟了子進程(如nginx開啟多進程,os.fork,subprocess.Popen等)
父進程發起請求,操作系統創建子進程
方式一:
from multiprocessing import Process import time import os def task(name): print('%s is running' %name) time.sleep(3) print('%s has done' %name) print('爹是:', os.getppid()) #me是: 13892 print('me是: ', os.getpid()) #me是: 7492 if __name__ == '__main__': # windows系統,開啟子進程的操作一定要放到這下麵 p=Process(target=task,args=('egon',)) # p=Process(target=task,kwargs={'name':'egon'}) p.start() # 向操作系統發送請求,操作系統會申請記憶體空間,然後把父進程的數據拷貝給子進程,作為子進程的初始狀態 print('me是: ', os.getpid()) #me是: 13892 print('======主')#======主 egon is running egon has done
-
target 表示調用對象,即子進程要執行的任務
-
args 指定為target函數傳位置參數,是一個元組形式,必須有逗號
-
kwargs 表示調用對象的字典,kwargs={'name':'egon','age':18}
-
p.start() 啟動進程,並調用該子進程中的p.run()
方式二:
from multiprocessing import Process import time class MyProcess(Process): def __init__(self,name): super(MyProcess,self).__init__() self.name=name def run(self): print('%s is running' %self.name) time.sleep(3) print('%s has done' %self.name) if __name__ == '__main__': p=MyProcess('egon') p.start() print('主') #主 egon is running egon has done
-
p.run():進程啟動時運行的方法,正是它去調用target指定的函數,我們自定義類的類中一定要實現該方法
9.2 進程之間記憶體空間隔離
from multiprocessing import Process import time x=1000 def task(): time.sleep(3) global x x=0 print('兒子死啦',x) if __name__ == '__main__': print(x) p=Process(target=task) p.start() time.sleep(5) print(x) #1000 兒子死啦 0 1000
9.3 父進程等待子進程結束
from multiprocessing import Process import time x=1000 def task(): time.sleep(3) global x x=0 print('兒子死啦',x) if __name__ == '__main__': p=Process(target=task) p.start() p.join() # 讓父親在原地等 print(x) from multiprocessing import Process import time x=1000 def task(n): print('%s is runing' %n) time.sleep(n) if __name__ == '__main__': start_time=time.time() p_l=[] for i in range(1,4): p=Process(target=task,args=(i,)) p_l.append(p) p.start() for p in p_l: #1 is runing p.join() #3 is runing print('主',(time.time() - start_time)) #2 is runing 主 3.112313
9.4 進程對象的其他屬性
-
p.terminate():強制終止進程p,不會進行任何清理操作,如果p創建了子進程,該子進程就成了僵屍進程,使用該方法需要特別小心這種情況。如果p還保存了一個鎖那麼也將不會被釋放,進而導致死鎖
-
p.is_alive():如果p仍然運行,返回True
-
p.join([timeout]):主線程等待p終止(強調:是主線程處於等的狀態,而p是處於運行的狀態)。timeout是可選的超時時間,強調: p.join只能 join住start開啟的進程,而不能join住run開啟的進程
-
p.pid:進程的pid
from multiprocessing import Process import time,os x=1000 def task(n): print('%s is runing self:%s parent:%s' %(n,os.getpid(),os.getppid()))#self:13032 parent:9136 time.sleep(3) if __name__ == '__main__': p1=Process(target=task,args=(1,),name='任務1')#不指定name,p1.name是process-1 p1.start() print(p1.pid) # 13032 沒有p1.ppid print(p1.name) # 任務1 p1.terminate() # 向操作系統提交進程終止 p1.join() print(p1.is_alive()) # False print('主',os.getpid())# 主 9136