999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

Python函數并行執行方法的研究與實踐

2021-03-15 07:01:33秦子實
電腦知識與技術 2021年3期

秦子實

摘要:編程語言Python因其簡潔的語法、強大的表達能力、方便的基礎庫以及豐富的第三方庫,被廣泛應用于各個行業的日常業務中。近年來,隨著Python大版本的更新,引入了越來越多的并行執行基礎庫,以方便編程人員優化各種場景下的代碼執行效率。本文介紹了Python在近幾個版本中新引入的并行庫在常見場景下的代碼執行效率優化方法,方法具有代碼改動小、優化效果顯著、方便部署等特點,適合Python使用者在各場景中的程序執行效率優化。

關鍵詞:多進程;異步函數;Python

中圖分類號:TP393? ? ? 文獻標識碼:A

文章編號:1009-3044(2021)03-0050-02

1 概述

隨著Python語言在各行各業的廣泛使用,代碼規模和執行任務的數量都顯著增長,因此,部分代碼的執行效率優化越來越重要。同其他流行編程語言類似,新版的Python同樣引入了越來越多并行執行基礎庫,例如3.3版本以來大量引入的多進程庫multiprocessing,以及3.6版本以來大量引入的協程庫asyncio等。Python的諸多應用場景,均存在使用多核CPU執行多任務程序的情形,例如通過網絡下載的線程任務,或是利用win32的API操作COM的進程任務。若使用單進程同步阻塞運行,則不能充分利用硬件的算力和I/O帶寬,大量的CPU周期浪費在等待響應中,導致執行時間成倍增長。

本文針對上述需求,根據Python并發庫的特點,按照不同場景研究并實踐了一套任務并行開發方法。該方法利用Python基礎庫,可以在現有代碼上實現大幅提升阻塞式代碼的執行效率。

2 進程并行

2.1 應用場景

在特定場景下,代碼必須在進程環境下運行,比較常見的是在使用pywin32的API操作COM組件的場景下,例如使用Python操作Office或建立WMI連接,此類場景中,必須為COM組件建立單獨的進程。本文以WMI連接為例,介紹多進程并發建立WMI連接。

2.2 實現方案

并發多個WMI連接時,每個連接均需要使用單獨的進程發起。對于此類并發多個相同或相似進程的場景,通常使用multiprocessing.pool.Pool類創建進程池實例,進而使用apply、map系列函數。

需要注意的是,在Windows系統上,當使用multiprocessing的程序有凍結并生成Windows可執行程序的需求時(例如使用py2exe、PyInstaller、cx_Freeze等打包程序),需要在使用多進程模塊前調用freeze_support函數。

在使用進程池建立WMI連接時,使用Pool創建進程池,并使用參數processes指定進程數,通常進程數小于邏輯核心數。

之后使用pool.imap_unordered生成一個進程池的可迭代對象,將WMI連接函數read_wmi_func傳入,并指定一個IP列表ip_list作為進程池中所有進程的參數。該可迭代對象用于遍歷并得到進程池中每個進程的返回值。

該函數的行為可概括為:創建若干個worker進程(數目由processes參數指定),每個worker初始化環境并運行read_wmi_func函數,并從ip_list中依次取出每個成員作為參數傳給各worker中的函數。

需要了解的是,“imap_unordered”為apply、map系列函數中的一個,函數名中的“i”即iterable,說明該函數返回可迭代對象,是一個惰性求值函數;“map”指分發任務的方式為map映射;“unordered”說明該函數在使用參數集合ip_list創建新進程時,不會依次等待前一個進程結束,即該函數的worker在完成當前任務后立刻取下一個參數并執行,而不是等待前面的worker執行完成再依次取參數。apply、map系列函數的命名均遵循此類規則。在示例的WMI場景中,任務直接并無先后次序,也無須相互等待依次完成,因此,使用“imap_unordered”的效率較高。

3 協程異步

3.1 技術背景

Python的協程解決方案是在3.6版本后逐步引入的,總體而言,協程是基于同一個線程的,即協程是單線程的。與以往的多線程解決方案不同的是,多線程通常是多個線程運行多個任務,每個任務都是阻塞式,即該線程中的任務執行完成后,才能繼續執行下一個進程。協程在一個線程中維護一個事件循環,協程中執行的事件均為非阻塞的,即一個事件執行后立即接著執行下一個事件,事件循環會輪詢檢查各事件是否執行完成,完成的獲得返回值或執行回調函數。

多線程方案通常存在資源鎖及搶占問題,在多個線程同時訪問資源產生;而協程為同一個線程,在不同的時間進行訪問,只需要梳理清楚執行流程,即可以同步方式編寫異步程序。

3.2 應用場景

以非阻塞方式運行一個Python函數,一般有兩個應用場景:將一個普通Python函數放入事件循環執行,或是直接執行一個異步函數。

目前,仍有大量Python庫尚不包含異步API,使用asyncio對普通函數進行封裝,并異步執行普通Python函數有較多的應用場景。而有部分常見庫的最新版本已經支持了異步API,支持直接通過asyncio.run()異步執行。

3.3 異步執行普通函數

使用asyncio執行普通函數,需要先將普通函數封裝為future對象,然后將這些future對象傳給asyncio.gather統一執行,并返回結果。http下載就是較為常見的場景,例如需要獲取某鏈接列表中的所有url內容,假設列表中有5個鏈接:同步模式下,即在循環中使用requests.get依次下載列表中的所有url內容并將其結果放入結果列表中,如此,需要的總時間大約為內容傳輸以及網絡延遲時間的5倍;異步模式下,asyncio將一次性發送5個GET請求并等待遠端返回,在遠端全部返回結果后結束并一次性返回所有結果,需要的總時間大約為所有GET請求中最慢的一個請求時間。

上述示例的返回即為有5個“”對象的列表,經測試,總時長約等于url請求的平均時常。示例中的代碼將requests.get這一普通函數通過事件循環的run_in_executor封裝為future對象,再使用gather統一執行這些future對象。

3.4 異步執行協程

同樣使用http下載的例子,httpx是一個與requests庫類似且具有異步API的常用網絡工具庫。

需要注意的是,在循環中創建協程,應當使用一個循環創建,再使用另一個循環等待結果,而不是在同一個循環中創建一個協程就等待一次結果,如此編寫則為使用同步方式運行協程,失去了異步方式提升I/O效率的功能。

4 結束語

本文介紹了在諸如I/O等存在較長阻塞時間的場景中,提升代碼執行效率的兩種常見方式,在Python中恰當地使用多進程或協程可以成倍提升代碼執行效率。特別的,Python默認C語言實現存在線程的全局解釋器鎖(global interpreter lock),因此正確的利用協程解決方案可以極大地提升Python線程的執行效率。

【通聯編輯:梁書】

主站蜘蛛池模板: 国产美女在线免费观看| 国产精品网曝门免费视频| 亚洲精品视频在线观看视频| 超碰精品无码一区二区| 亚洲日韩精品伊甸| 国产精品3p视频| 91国内外精品自在线播放| 高清免费毛片| 欧美日韩在线第一页| 国产极品嫩模在线观看91| 欧美高清三区| 国产人成在线视频| 白丝美女办公室高潮喷水视频| AV老司机AV天堂| 欧美第一页在线| 9cao视频精品| 亚洲国产91人成在线| 国产精品一区二区在线播放| 国内老司机精品视频在线播出| 操美女免费网站| 青青草原国产| 国产在线一二三区| 一级毛片免费观看不卡视频| 亚洲男人在线天堂| 久久黄色免费电影| 美女一级免费毛片| 欧美中文字幕无线码视频| 亚洲欧洲日韩综合色天使| 欧美啪啪视频免码| 国产大片喷水在线在线视频| 亚洲高清在线天堂精品| a国产精品| 国产主播一区二区三区| 久久影院一区二区h| 青青青国产在线播放| 91精品国产情侣高潮露脸| 人妻丰满熟妇AV无码区| 国产在线精品99一区不卡| 99这里只有精品在线| 亚洲国产精品一区二区第一页免 | 人妻中文字幕无码久久一区| 狠狠色婷婷丁香综合久久韩国 | 97se综合| 亚洲一区二区日韩欧美gif| 国产亚洲欧美另类一区二区| 日本福利视频网站| 久久午夜夜伦鲁鲁片不卡| 91福利免费视频| 97青草最新免费精品视频| 精品久久蜜桃| 国产黄在线免费观看| 日韩a在线观看免费观看| 亚国产欧美在线人成| 一级毛片无毒不卡直接观看| 99视频有精品视频免费观看| 国产乱论视频| 成人福利一区二区视频在线| 五月综合色婷婷| 91精品国产自产91精品资源| 亚洲中文无码av永久伊人| 亚洲综合狠狠| 青青操国产视频| 亚洲人成网18禁| 爱色欧美亚洲综合图区| 亚洲三级a| 国产精品永久不卡免费视频| 久久国产成人精品国产成人亚洲 | 日韩成人午夜| 黄色网页在线观看| 国产成人一区二区| 久久午夜夜伦鲁鲁片无码免费| 在线日韩一区二区| 亚洲国产精品成人久久综合影院| 暴力调教一区二区三区| 免费一级全黄少妇性色生活片| 国产成人禁片在线观看| 亚洲愉拍一区二区精品| 在线观看国产网址你懂的| 国产青青操| 欧美伦理一区| 黄色网页在线播放| 爱做久久久久久|