<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 1687字,需瀏覽 4分鐘

           ·

          2020-12-04 20:51

          1. GIL

          熟悉python的都知道,在C語言寫的python解釋器中存在全局解釋器鎖,由于全局解釋器鎖的存在,在同一時間內(nèi),python解釋器只能運行一個線程的代碼,這大大影響了python多線程的性能。而這個解釋器鎖由于歷史原因,現(xiàn)在幾乎無法消除。

          python GIL 之所以會影響多線程等性能,是因為在多線程的情況下,只有當(dāng)線程獲得了一個全局鎖的時候,那么該線程的代碼才能運行,而全局鎖只有一個,所以使用python多線程,在同一時刻也只有一個線程在運行,因此在即使在多核的情況下也只能發(fā)揮出單核的性能。

          2. 多線程處理IO密集型任務(wù)

          IO密集型任務(wù)指的是系統(tǒng)的CPU性能相對硬盤、內(nèi)存要好很多,此時,系統(tǒng)運作,大部分的狀況是CPU在等I/O (硬盤/內(nèi)存) 的讀/寫操作,此時CPU Loading并不高。涉及到網(wǎng)絡(luò)、磁盤IO的任務(wù)都是IO密集型任務(wù)。一個線程執(zhí)行IO密集型任務(wù)的時候,CPU處于閑置狀態(tài),因此GIL會被釋放給其他線程,從而縮短了總體的等待運行時間。

          from?concurrent.futures?import?ThreadPoolExecutor
          from?time?import?sleep,?time
          #?Worker數(shù)量
          N?=?4
          #?建立線程池
          pool?=?ThreadPoolExecutor(max_workers=N)

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

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

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

          2.2 使用串行的方式處理

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

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

          2.3 使用多線程處理

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

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

          2.4 計算函數(shù)運行時間

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

          3. 多線程CPU密集型任務(wù)

          CPU密集型任務(wù)的特點是要進行大量的計算,消耗CPU資源,比如計算圓周率、對視頻進行高清解碼等等,全靠CPU的運算能力。一個線程執(zhí)行CPU密集型任務(wù)的時候,CPU處于忙碌狀態(tài),運行1000個字節(jié)碼之后GIL會被釋放給其他線程,加上切換線程的時間有可能會比串行代碼更慢。

          3.1 定義一個CPU密集型函數(shù)

          該函數(shù)會對[1, x]之間的整數(shù)進行求和。

          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 使用串行的方式處理

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

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

          3.3 使用多線程處理

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

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

          3.4 計算函數(shù)運行時間

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

          參考文章

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

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

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

          Github:?https://github.com/tushushu


          更多閱讀



          有人在代碼里下毒!慎用 pip install 命令


          pip 20.3 新版本發(fā)布!即將拋棄 Python 2.x


          5 分鐘掌握 Python 中的 Hook 鉤子函數(shù)


          特別推薦


          程序員摸魚指南


          為你精選的硅谷極客資訊,
          來自FLAG巨頭開發(fā)者、技術(shù)、創(chuàng)投一手消息




          點擊下方閱讀原文加入社區(qū)會員



          點贊鼓勵一下

          瀏覽 28
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  99精品在线观看免费 | 91射在线播放 | 日本一级A片在线观看视频 | 在线水蜜桃 | 欧洲无码在线播放 |