python的进程
多進程概念:
?由于GIL的存在,python中的多線程其實并不是真正的多線程,如果想要充分地使用多核CPU的資源,在python中大部分情況需要使用多進程。python提供了非常好用的多線程包(multiprocessing),只需要定義一個函數,Python會完成其他所有事情。借助這個包,可以輕松完成從單進程到并發執行的轉換。multiprocessing支持子進程、通信和共享數據、執行不同形式的同步,提供了Process、Queue、Pipe、Lock等組件。
multiprocessing包是Python中的多進程管理包。與threading.Thread類似,它可以利用multiprocessing.Process對象來創建一個進程。該進程可以運行在Python程序內部編寫的函數。該Process對象與Thread對象的用法相同,也有start(), run(), join()的方法。此外multiprocessing包中也有Lock/Event/Semaphore/Condition類 (這些對象可以像多線程那樣,通過參數傳遞給各個進程),用以同步進程,其用法與threading包中的同名類一致。所以,multiprocessing的很大一部份與threading使用同一套API,只不過換到了多進程的情境。
但在使用這些共享API的時候,我們要注意以下幾點:
- 在UNIX平臺上,當某個進程終結之后,該進程需要被其父進程調用wait,否則進程成為僵尸進程(Zombie)。所以,有必要對每個Process對象調用join()方法 (實際上等同于wait)。對于多線程來說,由于只有一個進程,所以不存在此必要性。
- multiprocessing提供了threading包中沒有的IPC(比如Pipe和Queue),效率上更高。應優先考慮Pipe和Queue,避免使用Lock/Event/Semaphore/Condition等同步方式 (因為它們占據的不是用戶進程的資源)。
- 多進程應該避免共享資源。在多線程中,我們可以比較容易地共享資源,比如使用全局變量或者傳遞參數。在多進程情況下,由于每個進程有自己獨立的內存空間,以上方法并不合適。此時我們可以通過共享內存和Manager的方法來共享資源。但這樣做提高了程序的復雜度,并因為同步的需要而降低了程序的效率。
Process.PID中保存有PID,如果進程還沒有start(),則PID為None。
window系統下,需要注意的是要想啟動一個子進程,必須加上那句if?__name__ == "main",進程相關的要寫在這句下面。
1 from multiprocessing import Process 2 import time,os 3 4 5 def f(name): 6 time.sleep(1) 7 print('%s,父進程:%s;子進程:%s'%(name,os.getppid(),os.getpid())) 8 9 if __name__ == "__main__": 10 p_list=[] 11 for i in range(8): # 若進程數超過系統本身CPU的核數,就會發生進程的切換 12 p=Process(target=f,args=('Adair',)) 13 p_list.append(p) 14 p.start() 15 for i in p_list: 16 p.join() # 防止出現僵尸進程 17 18 print("父進程執行結束!")
?
類式調用:
1 from multiprocessing import Process 2 import time,os 3 4 class MyProcess(Process): 5 def __init__(self): 6 super(MyProcess,self).__init__() 7 8 def run(self): 9 time.sleep(1) 10 print('%s,父進程:%s;子進程:%s'%(self.name,os.getppid(),os.getpid())) 11 12 if __name__ == "__main__": 13 p_list=[] 14 for i in range(3): 15 p = MyProcess() 16 p.start() 17 p_list.append(p) 18 19 for i in p_list: 20 i.join() 21 22 print("父進程結束!")
?Process類:
構造方法:
Process([group [,target [,name[,args[,kwarge]]]])
group:線程組,目前還沒實現,庫引用中提示必須是None
target:要執行的方法
name:進程名
args / kwargs:要傳入方法的參數
實例方法:
is_alive():返回進程是否在運行
join([timeout]):阻塞當前上下文環境的進程,直到調用此方法的進程終止或者達到指定的timeout(可選參數)
start():進程準備就緒,等待CPU調度
run():start()調用run方法,如果實例進程時未指定傳入的target,這start執行默認run()方法
terminate():不管任務是否完成,立即停止工作進程
屬性:
authkey
daemon:和進程的setDeamon功能一樣
exitcode(進程在運行時為None、如果為-N,表示被信號N結束)
name:進程名
pid:進程號
?
進程間通訊:
不同進程間內存是不共享的,要想實現兩個進程間的數據交換,可以用一下方法:
Queues
使用方法跟threading里的queue類似:
1 from multiprocessing import Process,Queue 2 3 def foo(q,n): 4 q.put([42,n,"Adair."]) 5 6 if __name__ == "__main__": 7 q = Queue() 8 # print("q:",q) 9 p_list=[] 10 for i in range(3): 11 p = Process(target=foo,args=(q,i)) 12 p_list.append(p) 13 p.start() 14 print(p.pid) 15 print(q.get()) 16 print(q.get()) 17 print(q.get()) 18 19 for i in p_list: 20 i.join()
?
轉載于:https://www.cnblogs.com/Adairye/p/10188126.html
總結
- 上一篇: 求一个古代qq网名。
- 下一篇: 云计算时代的数据库运行