1. GIL 熟悉python的都知道,,在C語(yǔ)言寫的python解釋器中存在全局解釋器鎖,由于全局解釋器鎖的存在,,在同一時(shí)間內(nèi),,python解釋器只能運(yùn)行一個(gè)線程的代碼,,這大大影響了python多線程的性能,。而這個(gè)解釋器鎖由于歷史原因,,現(xiàn)在幾乎無(wú)法消除。 python GIL 之所以會(huì)影響多線程等性能,,是因?yàn)樵诙嗑€程的情況下,,只有當(dāng)線程獲得了一個(gè)全局鎖的時(shí)候,那么該線程的代碼才能運(yùn)行,,而全局鎖只有一個(gè),,所以使用python多線程,在同一時(shí)刻也只有一個(gè)線程在運(yùn)行,,因此在即使在多核的情況下也只能發(fā)揮出單核的性能。 2. 多線程處理IO密集型任務(wù) IO密集型任務(wù)指的是系統(tǒng)的CPU性能相對(duì)硬盤,、內(nèi)存要好很多,,此時(shí),系統(tǒng)運(yùn)作,,大部分的狀況是CPU在等I/O (硬盤/內(nèi)存) 的讀/寫操作,,此時(shí)CPU Loading并不高。涉及到網(wǎng)絡(luò),、磁盤IO的任務(wù)都是IO密集型任務(wù),。一個(gè)線程執(zhí)行IO密集型任務(wù)的時(shí)候,CPU處于閑置狀態(tài),因此GIL會(huì)被釋放給其他線程,,從而縮短了總體的等待運(yùn)行時(shí)間,。 from concurrent.futures import ThreadPoolExecutor 2.1 定義一個(gè)IO密集型函數(shù) 該函數(shù)會(huì)“睡眠”x秒。
2.2 使用串行的方式處理 遍歷一個(gè)列表的所有元素,,執(zhí)行func函數(shù),。 def process_array(arr): 2.3 使用多線程處理 通過(guò)線程池的map方法,可以將同一個(gè)函數(shù)作用在列表中的所有元素上,。
2.4 計(jì)算函數(shù)運(yùn)行時(shí)間
def time_it(fn, *args):
time_it(fast_process_array, [1, 2, 3])
3. 多線程CPU密集型任務(wù) CPU密集型任務(wù)的特點(diǎn)是要進(jìn)行大量的計(jì)算,,消耗CPU資源,比如計(jì)算圓周率,、對(duì)視頻進(jìn)行高清解碼等等,,全靠CPU的運(yùn)算能力。一個(gè)線程執(zhí)行CPU密集型任務(wù)的時(shí)候,,CPU處于忙碌狀態(tài),,運(yùn)行1000個(gè)字節(jié)碼之后GIL會(huì)被釋放給其他線程,加上切換線程的時(shí)間有可能會(huì)比串行代碼更慢,。 3.1 定義一個(gè)CPU密集型函數(shù) 該函數(shù)會(huì)對(duì)[1, x]之間的整數(shù)進(jìn)行求和,。 def cpu_bound_func(x): 3.2 使用串行的方式處理 遍歷一個(gè)列表的所有元素,執(zhí)行func函數(shù),。
3.3 使用多線程處理 通過(guò)線程池的map方法,,可以將同一個(gè)函數(shù)作用在列表中的所有元素上。 def fast_process_array(arr): 3.4 計(jì)算函數(shù)運(yùn)行時(shí)間
Finish sum from 1 to 10000000!
Finish sum from 1 to 10000000! 參考文章 1,、Python中的GIL鎖: 2,、什么是CPU密集型、IO密集型,?: 作者:李小文,,先后從事過(guò)數(shù)據(jù)分析、數(shù)據(jù)挖掘工作,,主要開(kāi)發(fā)語(yǔ)言是Python,,現(xiàn)任一家小型互聯(lián)網(wǎng)公司的算法工程師。 |
|