文章來源:https://www.liaoxuefeng.com/discuss/969955749132672/1294194291245090
先說兩句:什么是進程耸采?有什么用?——ok十拣,那我問你,你能一手畫圓一手畫方嗎艰亮?——我猜不能橄务。但計算機就不一樣了,一邊繪制正方體一邊繪制球體都是小case(屏幕上自動繪制圖形)娃圆,這是因為計算機啟動了另一個"大腦"來處理另一個任務,即兩個“大腦”分別同時畫兩個圖形 效率X2蛾茉!我們之前的寫程序都是計算機一個“大腦”在工作讼呢!ok,那怎么啟動計算機其他的大腦呢谦炬?——啟動另一個進程就可以了悦屏!
1、創(chuàng)建進程:
import multiprocessing
import time
def action(a, b): # 待會兩個進程要執(zhí)行的任務↓
for i in range(30): # 循環(huán)30次
print(a, ' ', b)
time.sleep(0.1) # 等待0.1s
if __name__ == '__main__': # 這行代碼很重要键思,新建進程的時候都加上它4∨馈!原因不用管(我也不知道233)
jc1 = multiprocessing.Process(target=action, args=('進程一', 0)) # 準備建立一個進程:multiprocessing.Process()
jc2 = multiprocessing.Process(target=action, args=('進程二', 1)) # 再準備建立一個新進程吼鳞,這是基本格式記住←
# 必要參數(shù)target:指定進程要執(zhí)行的任務(這里是執(zhí)行函數(shù) action),必要參數(shù)args:直譯成中文就是'參數(shù)'看蚜,顧名思義就是前面target的參數(shù),即action的參數(shù)赔桌,注意args是個元組供炎,所以args后的參數(shù)寫成tuple元組格式。直接寫target('進程一',0)一定報錯的
jc1.start() # 將蓄勢待發(fā)的jc1進程正式啟動<驳场音诫!
jc2.start() # 同上...
jc1.join() # 等待進程jc1將任務執(zhí)行完...
jc2.join() # ...
print('jc1,jc2任務都已執(zhí)行完畢')
jc1.close() # 徹底關閉進程jc1
jc2.close() # ...
輸出結果是兩個進程同時且連續(xù)打印0、1
2雪位、Pool:(進程池)
import time
import os
def action1(a, b=50):
for i in range(b):
print(a, os.getpid(), ' ', i) # os.getpid(): pid簡單來說就是每個進程的“身份證”
time.sleep(0.1)
if __name__ == '__main__': # 還要添加這行竭钝,否則可能出現(xiàn)異常
ci = Pool(3) # 創(chuàng)建一個進程池,容量為3個進程
ci.apply_async(action1, args=('進程一',)) # 啟動第一個子進程...
ci.apply_async(action1, args=('進程二', 50)) # 和普通進程的啟動方式有很大不同仔細看
ci.apply_async(action1, args=('進程三', 60)) # Pool的最基本格式記住←
# 注意:程序現(xiàn)在有4個進程在運行:上面的三個子進程 和一個最為核心的:主進程
ci.close() # 關閉進程池(但池子內(nèi)已啟動的子進程還會繼續(xù)進行)
ci.join() # 等待進程池內(nèi)的所有子進程完畢
print('比如說這最后的一行輸出就是主進程執(zhí)行任務打印出來的')
主進程(父進程)全程干了什么雹洗?創(chuàng)建進程池香罐、啟動子進程、關閉進程池队伟、等待子進程完畢穴吹、打印最后一行
3幽勒、進程間的通信:
import multiprocessing
def foo(aa):
ss = aa.get() # 管子的另一端放在子進程這里嗜侮,子進程接收到了數(shù)據(jù)
print('子進程已收到數(shù)據(jù)...')
print(ss) # 子進程打印出了數(shù)據(jù)內(nèi)容...
if __name__ == '__main__': # 要加這行...
tx = multiprocessing.Queue() # 創(chuàng)建進程通信的Queue,你可以理解為我拿了個管子來...
jc = multiprocessing.Process(target=foo, args=(tx,)) # 創(chuàng)建子進程
jc.start() # 啟子子進程
print('主進程準備發(fā)送數(shù)據(jù)...')
tx.put('有內(nèi)鬼,終止交易锈颗!') # 將管子的一端放在主進程這里顷霹,主進程往管子里丟入數(shù)據(jù)↑
jc.join()
這種方法可以實現(xiàn)任意進程間的通信,這里寫的是主击吱、子進程間的通信