#原創,轉載請聯繫python
在開始以前,咱們要知道什麼是進程。道理很簡單,你平時電腦打開QQ客戶端,就是一個進程。再打開一個QQ客戶端,又是一個進程。那麼,在python中如何用一篇代碼就能夠開啓幾個進程呢?經過一個簡單的例子來演示:算法
import multiprocessing import time def task1(): while True: time.sleep(1) print("I am task1") def task2(): while True: time.sleep(2) print("I am task2") if __name__ == '__main__': p1 = multiprocessing.Process(target=task1) # multiprocessing.Process建立了子進程對象p1 p2 = multiprocessing.Process(target=task2) # multiprocessing.Process建立了子進程對象p2 p1.start() # 子進程p1啓動 p2.start() # 子進程p2啓動 print("I am main task") # 這是主進程的任務
輸出結果:
I am main task
I am task1
I am task2
I am task1
I am task1
I am task2
I am task1
I am task1
I am task2
...
...
能夠看到子進程對象是由multiprocessing模塊中的Process類建立的。除了p1,p2兩個被建立的子進程外。固然還有主進程。主進程就是咱們從頭至尾的代碼,包括子進程也是由主進程建立的。併發
注意的點有:app
1.首先解釋一下併發:併發就是當任務數大於cpu核數時,經過操做系統的各類任務調度算法,實現多個任務「一塊兒」執行。(實際上總有一些任務不在執行,由於切換任務至關快,看上去想同時執行而已。)函數
2.當是併發的狀況下,子進程與主進程的運行都是沒有順序的,CPU會採用時間片輪尋的方式,哪一個程序先要運行就先運行哪一個。測試
3.主進程會默認等待全部子進程執行完畢後,它纔會退出。因此在上面的例子中,p1,p2子進程是死循環進程,主進程的最後一句代碼print("I am main task")雖然運行完了,可是主進程並不會關閉,他會一直等待着子進程。spa
4.主進程默認建立的是非守護進程。注意,結合3.和5.看。操作系統
5.可是!可是!若是子進程是守護進程的話,那麼主進程運行完最後一句代碼後,主進程會直接關閉,無論你子進程運行完了沒有!線程
-------------------------------------------------------------------------------------------------------------我是一條分割線------------------------------------------------------------------------------------------------------------------------------------code
不相信?
那咱們來測試下
import multiprocessing import time def task1(): while True: time.sleep(1) print("I am task1") def task2(): while True: time.sleep(2) print("I am task2") if __name__ == '__main__': p1 = multiprocessing.Process(target=task1) p2 = multiprocessing.Process(target=task2) p1.daemon = True # 設置p1子進程爲守護進程 p2.daemon = True # 設置p2子進程爲守護進程 p1.start() p2.start() print("I am main task")
輸出結果:
I am main task
輸出結果是否是有點奇怪。爲何p1,p2子進程都沒有輸出的?
讓咱們來整理一下思路:
1.建立p1,p2子進程
2.設置p1,p2子進程爲守護進程
3.p1,p2子進程開啓
4.p1,p2子進程代碼裏面都有休眠時間,因此cpu爲了避免浪費時間,先作主進程後續的代碼。
5.執行主進程後續的代碼,print("I am main task")
6.主進程後續的代碼執行完成了,因此剩下的子進程是守護進程的,全都要關閉了。可是,若是主進程的代碼執行完了,有兩個子進程,一個是守護的,一個非守護的,怎麼辦呢?其實,他會等待非守護的那個子進程運行完,而後三個進程一塊兒關閉。
7.p1,p2還在休眠時間內就被終結生命了,因此什麼輸出都沒有。
裏面涉及到兩個知識點:
1.當主進程結束後,會發一個消息給子進程(守護進程),守護進程收到消息,則當即結束
2.CPU是按照時間片輪尋的方式來運行多進程的。哪一個合適的哪一個運行,若是你的子進程裏都有time.sleep。那我CPU爲了避免浪費資源,確定先去幹點其餘的事情啊。
那麼,守護進程隨時會被中斷,他的存在乎義在哪裏的?
其實,守護進程主要用來作與業務無關的任務,可有可無的任務,無關緊要的任務,好比內存垃圾回收,某些方法的執行時間的計時等。
-------------------------------------------------------------------------------------------------------------我是一條分割線------------------------------------------------------------------------------------------------------------------------------------
雖然知道怎麼簡單的建立子進程,可是若是要建立的子進程要傳入參數,應該怎麼操做呢?
import multiprocessing def task(a,b,*args,**kwargs): print("a") print("b") print(args) print(kwargs) if __name__ == '__main__': p1 = multiprocessing.Process(target=task,args=(1,2,3,4,5,6),kwargs={"name":"chichung","age":23}) p1.start() print("主進程已經運行完最後一行代碼啦")
輸出:
主進程已經運行完最後一行代碼啦
a
b
(3, 4, 5, 6)
{'name': 'chichung', 'age': 23}
子進程要運行的函數須要傳入變量a,b,一個元組,一個字典。咱們建立子進程的時候,變量a,b要放進元組裏面,task函數取的時候會把前兩個取出來,分別賦值給a,b了。
-------------------------------------------------------------------------------------------------------------我是一條分割線------------------------------------------------------------------------------------------------------------------------------------
建立的子進程有幾個經常使用的方法:
p.start | 開始執行子線程 |
p.name | 查看子進程的名稱 |
p.pid | 查看子進程的id |
p.is_alive | 判斷子進程是否存活 |
p.join(timeout) | 阻塞主進程,當子進程p運行完畢後,再解開阻塞,讓主進程運行後續的代碼 若是timeout=2,就是阻塞主進程2s,這2s內主進程不能運行後續的代碼。過了2s後,就算子進程沒有運行完畢,主進程也能運行後續的代碼 |
p.terminate | 終止子進程p的運行 |
import multiprocessing def task(a,b,*args,**kwargs): print("a") print("b") print(args) print(kwargs) if __name__ == '__main__': p1 = multiprocessing.Process(target=task,args=(1,2,3,4,5,6),kwargs={"name":"chichung","age":23}) p1.start() print("p1子進程的名字:%s" % p1.name) print("p1子進程的id:%d" % p1.pid) p1.join() print(p1.is_alive()) 輸出: p1子進程的名字:Process-1 p1子進程的id:19345 a b (3, 4, 5, 6) {'name': 'chichung', 'age': 23} False
這個沒什麼好說的,本身體會一下......
-------------------------------------------------------------------------------------------------------------我是一條分割線------------------------------------------------------------------------------------------------------------------------------------
進程之間是不能夠共享全局變量的,即便子進程與主進程。道理很簡單,一個新的進程,其實就是佔用一個新的內存空間,不一樣的內存空間,裏面的變量確定不可以共享的。實驗證實以下:
import multiprocessing g_list = [123] def task1(): g_list.append("task1") print(g_list) def task2(): g_list.append("task2") print(g_list) def main_process(): g_list.append("main_processs") print(g_list) if __name__ == '__main__': p1 = multiprocessing.Process(target=task1) p2 = multiprocessing.Process(target=task2) p1.start() p2.start() main_process()
輸出:
[123, 'main_processs']
[123, 'task1']
[123, 'task2']
一針見血了吧,哈哈~
----------------------------------------------------------------------------------------------------------我是一條結束線,謝謝觀看~-----------------------------------------------------------------------------------------------------------------------