嘗試學習python的多進程模組,對比多線程,大概的區別在:python
1.多進程的處理速度更快多線程
2.多進程的各個子進程之間交換數據很不方便app
進程基本使用multicore()dom
進程池優化進程的調用multicore_pool(),在使用進程池的時候,運許函數有return,而基本用法中進程是接收不了return的async
進程隊列用法,大部分方法和python的基本隊列是一致的,函數
q=mp.Queue() 聲明
q.put() 添加
q.get() 釋放
q.empty() 判斷是否是空的
""" Created on Tue Dec 5 09:00:00 2017 @author: hellcat """ import time import numpy as np import threading as td import multiprocessing as mp def job(q): for i in range(3): q.put(i) def multicore(): q=mp.Queue() ps = [mp.Process(target=job,args=(q,)), mp.Process(target=job,args=(q,))] # 基本的子進程建立方法 for p in ps: p.start() time.sleep(3) for p in ps: p.join() # 須要協調結束 while True: if q.empty() != True: print(q.get()) else: break def multithread(): q=mp.Queue() ps = [td.Thread(target=job,args=(q,)), td.Thread(target=job,args=(q,))] # 基本的子線程建立方法 for p in ps: p.start() time.sleep(3) for p in ps: p.join() while True: if q.empty() != True: print(q.get()) else: break def job_pool(q): res0 = 0 for i in range(np.random.randint(10)): res0 += i**3 return res0 def multicore_pool(): pool = mp.Pool(processes=2) # 初始化進程池,能夠指定進程數 res1 = pool.map(job_pool,range(20)) # map方法在線程池中同時添加多個線程 print(res1) # 返回值爲函數的return res2 = [pool.apply_async(job_pool,(i,)) for i in range(20)] # 在進程池中單個添加進程 print([res.get() for res in res2]) # 注意此時每一個進程的返回並不直接是return,須要get方法獲得的纔是return # for res in res2: # print(res.get()) if __name__=='__main__': # multicore() # multithread() multicore_pool()
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Tue Dec 5 10:15:58 2017 @author: hellcat """ import time import multiprocessing as mp def job(v,num,l): # 須要把共享變量實例做爲參數傳入才行 l.acquire() # 進程鎖鎖住 for _ in range(10): time.sleep(0.1) v.value += num # 獲取共享變量的值,並進行操做 print(v.value) l.release() # 進程鎖釋放 def muticore(): l = mp.Lock() # 實例化進程鎖 v = mp.Value('i',0) # 實例化共享變量 # p = mp.Pool(processes=2) # p.map(job,((v,1,l),(v,3,l))) p1 = mp.Process(target=job,args=(v,1,l)) p2 = mp.Process(target=job,args=(v,3,l)) p1.start() p2.start() p1.join() p2.join() if __name__=='__main__': muticore()
不一樣於多線程使用全局變量就能夠以共享變量,多進程必須使用 v = mp.Value('i',0)這樣的語句聲明變量(其實還能夠是mp.Array('i',[1,2,3]),注意,這裏只能是1維的list,[[1,2]]這樣都是不能夠的),並將v做爲參數傳給函數,在函數內部使用的時候也須要使用v.value來喚醒其值。學習
進程鎖會在鎖住時阻止其餘進程使用共享變量,因此能夠看到輸出中先執行了10次+1,而後執行了10次+3,而不使用進程鎖+1和+3會無規律的交替進行:優化
註釋掉進程鎖:ui
1
4
5
8
9
12
13
16
17
20
21
24
25
28
29
32
33
36
37
40線程使用進程鎖(上面代碼沒有註釋掉進程鎖):
1234567891013161922252831343740