在類unix操作系統下,可以用 os.fork() 創建一個新的進程,windows系統不可以: 在執行了 os.fork() 這一句之後,會有兩個進程同時向下執行, 返回的 ret 分別是 0(子進程)的 和 大於0(父進程)的 , getpid() 是獲取當前進程的pid getppid() 是 ...
在類unix操作系統下,可以用 os.fork() 創建一個新的進程,windows系統不可以:
import os ret = os.fork() print('ret=%d' % ret) if ret == 0: print('這是子進程:%d,繼承自:%d' % (os.getpid(), os.getppid())) else: print('這是父進程:%d' % os.getpid()) >>>ret=0 這是子進程:1537,繼承自:1536 ret=1537 這是父進程:1536
在執行了 os.fork() 這一句之後,會有兩個進程同時向下執行, 返回的 ret 分別是 0(子進程)的 和 大於0(父進程)的 ,
getpid() 是獲取當前進程的pid getppid() 是獲取父進程的 pid 所以可以看出子進程 1537繼承自1536.
註意父進程的結束並不會導致子進程的停止.
所以,一般,用 multiprocessing 模塊來創建一個新的進程,多系統通用:
from multiprocessing import Process import time import test2 if __name__ == '__main__': p = Process(target=test2.test) p.start() while True: print('----mian----') time.sleep(1) >>>----mian---- ----test---- ----mian---- ----test----
target 裡面是子進程調用對象的名稱. (函數放在這個文件裡面執行有bug,所以放在了 test2.py 文件裡面,不加if __name__ == '__main__': 這一行也會有bug)
Process語法結構如下:
Process([group [, target [, name [, args [, kwargs]]]]])
-
target:表示這個進程實例所調用對象;
-
args:表示調用對象的位置參數元組;
-
kwargs:表示調用對象的關鍵字參數字典;
-
name:為當前進程實例的別名;
-
group:大多數情況下用不到;
Process類常用方法:
-
is_alive():判斷進程實例是否還在執行;
-
join([timeout]):是否等待進程實例執行結束,或等待多少秒;
-
start():啟動進程實例(創建子進程);
-
run():如果沒有給定target參數,對這個對象調用start()方法時,就將執行對象中的run()方法;
-
terminate():不管任務是否完成,立即終止;
Process類常用屬性:
-
name:當前進程實例別名,預設為Process-N,N為從1開始遞增的整數;
- pid:當前進程實例的PID值;
還有一種方式創建進程,就是Process子類創建子進程, 因為 p.start() 是調用 p的run() 方法,所以需要重寫run方法:
class MyProcess(Process): def run(self): while True: print('----1----') time.sleep(1) if __name__ == '__main__': p = MyProcess() p.start() while True: print('main') time.sleep(1) >>>main ----1---- main ----1----
當然,還有更加簡單的方法創建進程.那就是進程池:
if __name__ == '__main__': pool = Pool(3) #最多三個進程 for i in range(10): pool.apply_async(test2.test, (i,)) #添加任務 如果換成 pool.apply() 那麼會以堵塞的方式添加任務,一個進程執行完才能添加下一個進程 pool.close() #關閉進程池,不能再添加任務 pool.join() #等待進程池裡的任務完成
需要註意的是,進程池並不和Process一樣會等待子進程的結束,而是任務完成之後馬上結束主進程,所以需要 pool.join() 等待子進程結束.