一、選擇操作系統
高性能多任務編程需要選擇合適的操作系統。因為windows下創建子進程是通過重新加載py程序文件;而linux和mac創建子進程是通過復制父進程的內存空間,所以在windows平臺下運行多進程python程序的效率遠不如在linux和mac平臺下運行。要追求高性能多任務運行python程序的,推薦使用linux或mac操作系統。
二、分析任務類型
高性能多任務編程有三種方式:
- 多進程,追求高運算:
任務類型:計算多IO少時,建議使用進程池的方式來編程。進程池中進程的數量一般推薦為CPU內核數的一至兩倍。多進程程序運行時是并行執行。
常見任務:科學計算、數據分析等。
注意:創建進程開銷極大,進程之間數據隔離,多進程存在數據不安全的情況,可規避所有IO。
- 多線程,運用最多:
任務類型:IO多計算少時,建議使用線程池的方式來編程。線程池中線程的數量一般推薦為CPU內核數的四到五倍,至多不超過十倍。多線程程序運行時是并發執行(由于GIL鎖造成python多線程執行時不能并行執行)。
常見任務:爬蟲等。
注意:創建線程開銷小,線程之間數據共享,多線程存在數據不安全的情況,可規避所有IO。
- 協程,追求高并發:
任務類型:IO多計算少且需要大幅度提高并發數時,建議使用協程或多進程+多線程+協程的方式。
常見任務:爬蟲、網絡服務、web服務器等。
注意:創建協程開銷極小,線程之間數據共享,多線程不存在數據不安全的情況,但只能規避部分IO。
三、Python解釋器類型
目前大家用得最多的是CPython,它是用C語言實現的Python解釋器,也是官方的并且是使用最廣泛的Python解釋器,它的軟件包和兼容性最佳,CPython最新版本是3.9.1。官網是https://www.python.org/ 。
如果要追求高性能的話目前值得推薦的解釋器是PyPy,PyPy提供了JIT編譯器和沙盒功能,因此運行速度比CPython要快,它的軟件包和兼容性不如CPython,Pypy最新版本是3.7。官網是https://www.pypy.org/ 。
四、注意事項
高性能多任務編程使用線程池的方式最多,要注意python線程編程的一個缺陷,即不能在線程外部關閉超時的線程。所以需要在任務內部對超時情況做處理。下面寫一個簡單的模擬爬蟲案例:
代碼:
from concurrent.futures import ThreadPoolExecutor
import requests
url = [('csdn', 'https://www.csdn.net/'), ('cnblogs', 'https://www.cnblogs.com/'),
('baidu', 'https://www.baidu.com/'), ('toutiao', 'https://www.toutiao.com/'),
('google', 'https://www.google.com/')]
def get(site):
try:
r = requests.get(site[1], timeout=5) # 設置超時時限為5秒
except requests.exceptions.ConnectTimeout:
return site[0], '超時'
return site[0], '正常'
if __name__ == "__main__":
p_list = []
with ThreadPoolExecutor(max_workers=5) as e:
ret = e.map(get, url)
for i in ret:
print(f'網站“{i[0]}”下載情況是“{i[1]}”')
輸出:
網站“csdn”下載情況是“正?!?網站“cnblogs”下載情況是“正?!?網站“baidu”下載情況是“正?!?網站“toutiao”下載情況是“正常”
網站“google”下載情況是“超時”
說明:
我們需要多任務執行的是get函數,它用來下載網頁。在get中要對io操作進行超時預判,即超過5秒獲取不到結果的網站放棄爬取。假設不設超時預判會導致線程一直反復爬取但一直獲取不到數據而陷入死循環,極其影響整體影響效率。
總結:
因為python多線程無法從外部結束超時的線程,所以在多任務編程中要在函數內部對可能存在異常的任務做超時判斷及處理。
版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。