久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Python 中用多線程進(jìn)行多任務(wù)處理

 F2967527 2020-12-07

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
from time import sleep, time
# Worker數(shù)量
N = 4
# 建立線程池
pool = ThreadPoolExecutor(max_workers=N)

2.1 定義一個(gè)IO密集型函數(shù)

該函數(shù)會(huì)“睡眠”x秒。

def io_bound_func(x):
    sleep(x)
    print('Sleep for %d seconds.' % x)

2.2 使用串行的方式處理

遍歷一個(gè)列表的所有元素,,執(zhí)行func函數(shù),。

def process_array(arr):
    for x in arr:
        io_bound_func(x)

2.3 使用多線程處理

通過(guò)線程池的map方法,可以將同一個(gè)函數(shù)作用在列表中的所有元素上,。

def fast_process_array(arr):
    for x in pool.map(io_bound_func, arr):
        pass

2.4 計(jì)算函數(shù)運(yùn)行時(shí)間

  • 串行版本的運(yùn)行時(shí)間 = 1 + 2 + 3 = 6秒
  • 多線程版本的運(yùn)行時(shí)間 = max(1, 2, 3) = 3秒
def time_it(fn, *args):
    start = time()
    fn(*args)
    print('%s版本的運(yùn)行時(shí)間為 %.5f 秒!' % (fn.__name__, time() - start))
time_it(process_array, [123])
Sleep for 1 seconds.
Sleep for 2 seconds.
Sleep for 3 seconds.
process_array版本的運(yùn)行時(shí)間為 6.00883 秒!
time_it(fast_process_array, [123])
Sleep for 1 seconds.
Sleep for 2 seconds.
Sleep for 3 seconds.
fast_process_array版本的運(yùn)行時(shí)間為 3.00300 秒!

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):
    tot = 0
    a = 1
    while a <= x:
        tot += x
        a += 1
    print('Finish sum from 1 to %d!' % x)
    return tot

3.2 使用串行的方式處理

遍歷一個(gè)列表的所有元素,執(zhí)行func函數(shù),。

def process_array(arr):
    for x in arr:
        cpu_bound_func(x)

3.3 使用多線程處理

通過(guò)線程池的map方法,,可以將同一個(gè)函數(shù)作用在列表中的所有元素上。

def fast_process_array(arr):
    for x in pool.map(cpu_bound_func, arr):
        pass

3.4 計(jì)算函數(shù)運(yùn)行時(shí)間

  • 串行版本的運(yùn)行時(shí)間2.1秒
  • 多線程版本的運(yùn)行時(shí)間2.2秒
def time_it(fn, *args):
    start = time()
    fn(*args)
    print('%s版本的運(yùn)行時(shí)間為 %.5f 秒!' % (fn.__name__, time() - start))
time_it(process_array, [10**710**710**7])
Finish sum from 1 to 10000000!
Finish sum from 1 to 10000000!
Finish sum from 1 to 10000000!
process_array版本的運(yùn)行時(shí)間為 2.10489 秒!
time_it(fast_process_array, [10**710**710**7])
Finish sum from 1 to 10000000!
Finish sum from 1 to 10000000!
Finish sum from 1 to 10000000!
fast_process_array版本的運(yùn)行時(shí)間為 2.20897 秒!

參考文章

1,、Python中的GIL鎖:https://www.jianshu.com/p/c75ed8a6e9af

2,、什么是CPU密集型、IO密集型,?:https://www.cnblogs.com/tusheng/articles/10630662.html

作者:李小文,,先后從事過(guò)數(shù)據(jù)分析、數(shù)據(jù)挖掘工作,,主要開(kāi)發(fā)語(yǔ)言是Python,,現(xiàn)任一家小型互聯(lián)網(wǎng)公司的算法工程師。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多