多進程(二)

進程池 在使用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())
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章