Process對象的其它方法與屬性(join)
一 Process對象的join方法
在主進程運行過程中如果想並發地執行其他的任務,我們可以開啟子進程,此時主進程的任務與子進程的任務分兩種情況
情況一:在主進程的任務與子進程的任務彼此獨立的情況下,主進程的任務先執行完畢後,主進程還需要等待子進程執行完畢,然後統一回收資源。
情況二:如果主進程的任務在執行到某一個階段時,需要等待子進程執行完畢後才能繼續執行,就需要有一種機制能夠讓主進程檢測子進程是否運行完畢,在子進程執行完畢後才繼續執行,否則一直在原地阻塞,這就是join方法的作用
# join方法 from multiprocessing import Process import time import os def task(name): # os.getppid()查看父進程編號 print("%s is running, parent id is <%s>" % (os.getpid(), os.getppid())) # os.getpid()查看自己進程編號 time.sleep(3) # 模擬任務運行一段時間 print("%s is done, parent id is <%s>" % (os.getpid(), os.getppid())) if __name__ == "__main__": # windows 一定要把開啟指令放到main下面 Linux無所謂 # Process(target=task, kargs={"name" : "子進程"}) # 方式1 p = Process(target=task, args=("子進程1",)) # 方式2 實例化得到一個對象 p.start() # (僅僅只是給操作系統發送了一個信號)開啟子進程,幫你執行task p.join() # 主進程會等子進程運行(主進程基於子進程執行的結果進行後續代碼的執行) print("主", os.getpid(), os.getppid()) # 此時的父進程是pycharm print(p.pid) # p對象下的pid(驗證僵屍進程)
10952 is running, parent id is <8624>
10952 is done, parent id is <8624>
主 8624 124
10952
from multiprocessing import Process import time import os def task(name, n): # os.getppid()查看父進程編號 print("%s is running" % name) # os.getpid()查看自己進程編號 time.sleep(n) # 模擬任務運行一段時間 if __name__ == "__main__": # windows 一定要把開啟指令放到main下面 Linux無所謂 start = time.time() p1 = Process(target=task, args=("子進程1", 5)) p2 = Process(target=task, args=("子進程2", 3)) p3 = Process(target=task, args=("子進程3", 2)) p_l = [p1, p2, p3] # p1.start() # (僅僅只是給操作系統發送了一個信號)開啟子進程,幫你執行task(不一定按順序) # p2.start() # p3.start() for i in p_l: # 簡寫 i.start() # p1.join() # 讓主進程等,連續三個並發執行 # p2.join() # p3.join() for p in p_l: p.join() print("主", (time.time()-start)) # 此時的父進程是pycharm
子進程1 is running
子進程2 is running
子進程3 is running
主 5.103978633880615
註意:
進程只要start就會在開始運行了,所以p1-p3.start()時,系統中已經有並發的進程了
join是讓主線程等,而p1-p3仍然是並發執行的,p1.join的時候,其余p2,p3,p4仍然在運行,等#p1.join結束,可能p2,p3早已經結束了,這樣p2.join,p3.join直接通過檢測,無需等待
所以3個join花費的總時間仍然是耗費時間最長的那個進程運行的時間
串行
# 串聯執行 from multiprocessing import Process import time import os def task(name, n): # os.getppid()查看父進程編號 print("%s is running" % name) # os.getpid()查看自己進程編號 time.sleep(n) # 模擬任務運行一段時間 if __name__ == "__main__": # windows 一定要把開啟指令放到main下面 Linux無所謂 start = time.time() p1 = Process(target=task, args=("子進程1", 5)) p2 = Process(target=task, args=("子進程2", 3)) p3 = Process(target=task, args=("子進程3", 2)) p1.start() # (僅僅只是給操作系統發送了一個信號)開啟子進程,幫你執行task(不一定按順序) p1.join() # 主程序再等P1 p2.start() # p2 才開始 p2.join() p3.start() p3.join() print("主", (time.time()-start)) # 此時的父進程是pycharm
子進程1 is running
子進程2 is running
子進程3 is running
主 10.3139066696167
二 Process對象的其他屬性或方法
進程對象的其他方法一:is_alive
# 了解 p.is_alive() from multiprocessing import Process import time import os def task(name): # os.getppid()查看父進程編號 print("%s is running, parent id is <%s>" % (os.getpid(), os.getppid())) # os.getpid()查看自己進程編號 time.sleep(3) # 模擬任務運行一段時間 print("%s is done, parent id is <%s>" % (os.getpid(), os.getppid())) if __name__ == "__main__": # windows 一定要把開啟指令放到main下面 Linux無所謂 # Process(target=task, kargs={"name" : "子進程"}) # 方式1 p = Process(target=task, args=("子進程1",)) # 方式2 實例化得到一個對象 p.start() # (僅僅只是給操作系統發送了一個信號)開啟子進程,幫你執行task print(p.is_alive()) # 判斷活著還是死的 p.join() # 主進程會等子進程運行(主進程基於子進程執行的結果進行後續代碼的執行) print("主", os.getpid(), os.getppid()) # 此時的父進程是pycharm print(p.pid) # p對象下的pid(驗證僵屍進程) print(p.is_alive()) # 判斷活著還是死的
進程對象的其他屬性:terminal
# 了解 p.terminate() from multiprocessing import Process import time import os def task(name): # os.getppid()查看父進程編號 print("%s is running, parent id is <%s>" % (os.getpid(), os.getppid())) # os.getpid()查看自己進程編號 time.sleep(3) # 模擬任務運行一段時間 print("%s is done, parent id is <%s>" % (os.getpid(), os.getppid())) if __name__ == "__main__": # windows 一定要把開啟指令放到main下面 Linux無所謂 # Process(target=task, kargs={"name" : "子進程"}) # 方式1 p = Process(target=task, args=("子進程1",)) # 方式2 實例化得到一個對象 p.start() # (僅僅只是給操作系統發送了一個信號)開啟子進程,幫你執行task print("主") p.terminate() # 給操作系統發出信號終止進程 time.sleep(3) print(p.is_alive())
進程對象的其他屬性:name
# 了解 p.name from multiprocessing import Process import time import os def task(name): # os.getppid()查看父進程編號 print("%s is running, parent id is <%s>" % (os.getpid(), os.getppid())) # os.getpid()查看自己進程編號 time.sleep(3) # 模擬任務運行一段時間 print("%s is done, parent id is <%s>" % (os.getpid(), os.getppid())) if __name__ == "__main__": # windows 一定要把開啟指令放到main下面 Linux無所謂 # Process(target=task, kargs={"name" : "子進程"}) # 方式1 p = Process(target=task, args=("子進程1",), name="我的進程") # 方式2 實例化得到一個對象 p.start() # (僅僅只是給操作系統發送了一個信號)開啟子進程,幫你執行task print("主") print(p.name) # 查看進程名稱(默認為Process-1)
三 練習題
1、改寫下列程序,分別別實現下述打印效果
from multiprocessing import Process
import time
import random
def task(n):
time.sleep(random.randint(1,3))
print(‘-------->%s‘ %n)
if __name__ == ‘__main__‘:
p1=Process(target=task,args=(1,))
p2=Process(target=task,args=(2,))
p3=Process(target=task,args=(3,))
p1.start()
p2.start()
p3.start()
print(‘-------->4‘)
效果一:保證最先輸出-------->4
-------->4
-------->1
-------->3
-------->2
效果二:保證最後輸出-------->4
-------->2
-------->3
-------->1
-------->4
效果三:保證按順序輸出
-------->1
-------->2
-------->3
-------->4
2、判斷上述三種效果,哪種屬於並發,哪種屬於串行?
Process對象的其它方法與屬性(join)