『Python』多進程處理
阿新 • • 發佈:2017-12-05
rgs map multicore 變量 實例化 read reat 嘗試 學習
嘗試學習python的多進程模組,對比多線程,大概的區別在:
1.多進程的處理速度更快
2.多進程的各個子進程之間交換數據很不方便
多進程調用方式
進程基本使用multicore()
進程池優化進程的調用multicore_pool(),在使用進程池的時候,運許函數有return,而基本用法中進程是接收不了return的
進程隊列用法,大部分方法和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會無規律的交替進行:
註釋掉進程鎖:
1
4
5
8
9
12
13
16
17
20
21
24
25
28
29
32
33
36
37
40使用進程鎖(上面代碼沒有註釋掉進程鎖):
1
2
3
4
5
6
7
8
9
10
13
16
19
22
25
28
31
34
37
40
『Python』多進程處理