標籤:條件 alt 高效 電腦 proc join 調用 strong 機器學習
並行編程的思想:分而治之,有兩種模型
1.MapReduce:將任務劃分為可並行的多個子任務,每個子任務完成後合并得到結果
例子:統計不同形狀的個數。
先通過map進行映射到多個子任務,分別統計個數,然後在用reduce進行歸納一下。
2.流水:將任務分為串列的多個子任務,每個子任務並行。ProductConsume
例子:
多個生產者進行並行,多個消費者進行並行。生產者生產出來東西放到隊列裡;隊列裡有東西時,消費者就可以進行消費,這樣雙方沒有太大的依賴關係。
為什麼要並行編程呢?
多核,雲端運算,使得實現並行編程的條件更容易滿足。
大資料(導致資料多),機器學習(複雜),高並發,使得並行編程很必要。
為什麼很少用呢?
任務分割,共用資料的訪問,死結,互斥,訊號量,利用管道,隊列通訊。線程,進程的管理。
這些概念使得並行編程的實現看上去很難
怎麼學並行編程?
庫: Threading,實現多線程
Multiprocess,實現多進程
Parallepython,實現分散式運算,同時解決CPU和網路資源受限問題。
Celery+RabbitMQ/Redis,可實現分布式任務隊列 Django和它搭配可實現非同步任務隊列
Gevent,可實現高效非同步IO,協成
2.進程和線程
CPU同一時刻只能調度一個進程,進程之間memory獨立,進程內線程共用memory。
我們主要解決的問題是:
處理序間通訊問題;
線程間同步問題
例子:計算10000000000自減到0,然後用多進程和多線程計算,看看他們用時多久
# -*- coding: utf-8 -*-# CopyRight by heibankeimport timefrom threading import Threadfrom multiprocessing import Processdef countdown(n): while n > 0: n -= 1 COUNT = 100000000 # 1億def thread_process_job(n, Thread_Process, job): """ n: 多線程或多進程數 Thread_Process: Thread/Process類 job: countdown任務 """ local_time=time.time() #執行個體化多線程或多進程 threads_or_processes = [Thread_Process(target=job,args=(COUNT//n,)) for i in xrange(n)]#學習這種寫法,很高大上,把不同的類放到列表裡邊 #threads_or_processes中儲存了三個Thread_process個對象 for t in threads_or_processes: t.start() #開始線程或進程,必須調用 for t in threads_or_processes: t.join() #等待直到該線程或進程結束 #join的作用是阻塞進程,直到所有的線程執行完畢之後,才可以執行後邊的語句 print n,Thread_Process.__name__," run job need ",time.time()-local_time if __name__=="__main__": print "Multi Threads" for i in [1,2,4]: thread_process_job(i,Thread, countdown) print "Multi Process" for i in [1,2,4]: thread_process_job(i,Process, countdown)
輸出結果:
從結果中看出來,多線程時,隨著線程的增多,時間反而更多;多進程隨著進程的增多,時間變少。原因是python的GIL機制
GIL
當有多個線程的時候,並不是真的是並行啟動並執行,實際上有一個鎖,誰申請到了誰運行
在python的原始解譯器CPython中存在著GIL(Global Interpreter Lock,全域解譯器鎖),因此在解釋執行python代碼時,會產生互斥鎖來限制線程對共用資源的訪問,直到解譯器遇到I/O操作或者操作次數達到一定數目時才會釋放GIL。
所以,雖然CPython的線程庫直接封裝了系統的原生線程,但CPython整體作為一個進程,同一時間只會有一個獲得GIL的線程在跑,其他線程則處於等待狀態。這就造成了即使在多核CPU中,多線程也只是做著分時切換而已。
所以它更適合處理I/O密集型的任務,不適合處理CPU密集型的任務。
不過muiltprocessing的出現,已經可以讓多進程的python代碼編寫簡化到了類似多線程的程度了。(連結:https://www.zhihu.com/question/23474039/answer/35418893)
這是兩個線程在運行,並不是並行,而是串列,紅色的線表示在申請cpu
四個線程在運行
進程可以快,而線程反而慢的原因是,我的電腦有多個核,進程可以進行並行的,而線程在python裡邊還是串列的,申請cpu也需要花費時間的
python並行編程