進程池
在使用Python進行系統管理時,特別是同時操作多個文件目錄或者遠程控制多臺主機,並行操作可以節約大量的時間。如果操作的對象數目不大時,還可以直接使用Process類動態的生成多個進程,十幾個還好,但是如果上百個甚至更多,那手動去限制進程數量就顯得特別的繁瑣,此時進程池就派上用場了。Pool類可以提供指定數量的進程供用戶調用,當有新的請求提交到Pool中時,如果池還沒有滿,就會創建一個新的進程來執行請求。如果池滿,請求就會告知先等待,直到池中有進程結束,纔會創建新的進程來執行這些請求。
Pool類中方法
apply():
函數原型:apply(func[, args=()[, kwds={}]])
該函數用於傳遞不定參數,主進程會被阻塞直到函數執行結束(不建議使用,並且3.x以後不再使用)。
map()
函數原型:map(func, iterable[, chunksize=None])
Pool類中的map方法,與內置的map函數用法行爲基本一致,它會使進程阻塞直到返回結果。
注意,雖然第二個參數是一個迭代器,但在實際使用中,必須在整個隊列都就緒後,程序纔會運行子進程。
返回結果爲一個list,序列傳入func後執行結果的list;
close()
關閉進程池(Pool),使其不再接受新的任務。
terminate()
立刻結束工作進程,不再處理未處理的任務。
join()
使主進程阻塞等待子進程的退出,join方法必須在close或terminate之後使用。
獲取CPU的核數
multiprocessing.cpu_count() #獲取cpu的核數
創建進程池
示例1:
#coding=utf-8
import multiprocessing
import os,time
import random
def m1(x):
time.sleep(random.random() * 4)
print("pid: ",os.getpid(), x*x)
return x*x
if __name__ == "__main__":
pool = multiprocessing.Pool(multiprocessing.cpu_count())
i_list = range(8)
res =pool.map(m1,i_list)#函數
print (type(res))
print(res)
示例2:
#coding=utf-8
import multiprocessing
import os,time
import random
def f(x):
return x * x
if __name__ == "__main__":
pool = multiprocessing.Pool(processes = 4)
#執行進程池中的一個子進程,執行結果存放在result中
result = pool.apply_async(f,[10])
print(result.get(timeout=1))#獲取執行結果
#多進程執行進程池中的進程
print(pool.map(f,range(10)))
多進程與單進程執行時間比較
#coding=utf-8
import time
from multiprocessing import Pool
def run(fn):
time.sleep(1)
return fn*fn
if __name__ == "__main__":
testFL = [1,2,3,4,5,6]
print("單進程執行: ")
start = time.time()
for fn in testFL:
run(fn)
end = time.time()
print("順序執行時間: ",end - start)
pool = Pool(5)#創建包含5個進程的進程池
t = time.time()
res = pool.map(run,testFL)
pool.close()#關閉進程池,不再接受新的任務
pool.join()#等待子進程執行結果退出
end = time.time()
print("進程池並行執行時間: ",end - t)
print(res)
Multiprocessing.Queue方法
>>> q = Queue()
>>> q.put(1)
>>> q.put(1)
>>> q.put(2)
>>> q.get()
1
>>> q.qsize()
2
>>> q.empty()
False
>>> q.full()
False
>>> q.get(timeout=1)
1
>>> q.get()
2
同步進程
使用Queue 同步進程間數據
示例1:
#coding=utf-8
from multiprocessing import Queue,Process
def func(queue):
queue.put("通過隊列同步的消息!")
if __name__ == "__main__":
q = Queue()#此處隊列q爲主進程的
p = Process(target = func,args=(q,))
#主進程、子進程是兩個獨立的進程,數據不共享
#生成子進程,通過主進程定義的隊列q同步主、子進程消息
p.start()
p.join()
print("主進程和子進程同步的隊列消息:",q.get())#獲取同步的隊列數據
multiprocessing.Queue類似於queue.Queue,一般用來多個進程間交互信息。Queue是進程和線程安全的。它實現了queue.Queue的大部分方法,但task_done()和join()沒有實現。multiprocessing.JoinableQueue是multiprocessing.Queue的子類,增加了task_done()方法和join()方法。task_done():用來告訴queue一個task完成。一般在調用get()時獲得一個task,在task結束後調用task_done()來通知Queue當前task完成。join():阻塞直到queue中的所有的task都被處理(即task_done方法被調用)。
示例2:
#coding=utf-8
from multiprocessing import Process,Queue
import random,time
def write(q):
for value in ["A","B","C"]:
print("Put %s to queue." %value)
q.put(value)
time.sleep(random.random())
def read(q):
time.sleep(1)
while not q.empty():
print("Get %s from queue." %q.get(True))
if __name__ == "__main__":
q = Queue()#主進程定義的隊列
p1 = Process(target=write,args=(q,))#兩個子進程同步進程數據
p2 = Process(target=read,args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
print("Done!")
示例3:
進程池間同步數據需要使用Manager裏面的Queue
#encoding=utf-8
from multiprocessing import Pool,Manager
def func(q):
print("*"*10)
q.put("12346")
if __name__ == "__main__":
manager = Manager()
q = manager.Queue()
pool = Pool(processes=4)
for i in range(5):
pool.apply_async(func,(q,))
pool.close()
pool.join()
print(q.qsize())
多進程(二)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.